AJS: Asynchronous
Templating in Node
(completing the async puzzle)
Who am I?
Evan Owen
Senior Developer @ LifeKraze

Lover of Ruby, JS, Redis, good
design and asynchronous code.
History of Templating
Old-school PHP: the template == your app
History of Templating
Old-school PHP: the template == your app
already flushed
History of Templating
Old-school PHP: the template == your app
already flushed




     blocking
OO PHP + template == worse
OO PHP + template == worse



   blocking
OO PHP + template == worse



   blocking




  nothing flushed!
Ruby + ERB template == just as bad
Ruby + ERB template == just as bad
          blocking
Ruby + ERB template == just as bad
          blocking




     nothing flushed!
Rails 3.1 Automatic Flushing == better
Rails 3.1 Automatic Flushing == better


<head> flushed
Rails 3.1 Automatic Flushing == better


<head> flushed

                             still blocking
Rails 3.1 Automatic Flushing == better


<head> flushed

                             still blocking




                            other db calls
                              must wait
What about Node?
  It’s non-blocking, right?

         WRONG.

Node will block (per-request)
at your first blocking function.
Node + EJS == not enough
Node + EJS == not enough



non-blocking
Node + EJS == not enough



non-blocking


      non-blocking
Node + EJS == not enough



  non-blocking


            non-blocking


blocking!
Node + existing async libs == frustrating

      node-asyncEJS
Node + existing async libs == frustrating

      node-asyncEJS




                        things to
                       worry about
Node + existing async libs == frustrating

      nun
Node + existing async libs == frustrating

      nun
                   more things to
                    worry about
Node + existing async libs == frustrating

      nun
                   more things to
                    worry about




                     no logic allowed,
                      loops are hard
What we need —
What we need —
1. Familiar, standard syntax
What we need —
1. Familiar, standard syntax
2. Nothing extra to learn or think about
What we need —
1. Familiar, standard syntax
2. Nothing extra to learn or think about
3. Completely non-blocking, able to
 continue rendering while waiting for
 callbacks
What we need —
1. Familiar, standard syntax
2. Nothing extra to learn or think about
3. Completely non-blocking, able to
 continue rendering while waiting for
 callbacks
4. Fast
Node + AJS == async, easy
Node + AJS == async, easy


              superset of JS
                 (similar to EJS)
Node + AJS == async, easy


              superset of JS
                  (similar to EJS)




             use callbacks naturally
               (can/should be defined in controller)
Node + AJS == async, easy


              superset of JS
                  (similar to EJS)




             use callbacks naturally
               (can/should be defined in controller)




               include partials
How AJS works —
How AJS works —
1. Parse source to an abstract syntax
 tree (AST)
How AJS works —
1. Parse source to an abstract syntax
 tree (AST)
2. Add “futures” hooks around callbacks
How AJS works —
1. Parse source to an abstract syntax
 tree (AST)
2. Add “futures” hooks around callbacks
3. Recompile and cache optimized JS
How AJS works —
1. Parse source to an abstract syntax
 tree (AST)
2. Add “futures” hooks around callbacks
3. Recompile and cache optimized JS
4. Execute code inside a VM that
 manages and handles async callbacks
How callbacks are handled —
How callbacks are handled —
1. At the exact spot a callback is passed to
 its async function, we create a “future”
 buffer.
How callbacks are handled —
1. At the exact spot a callback is passed to
 its async function, we create a “future”
 buffer.

2. We continue executing the template,
 flushing everything up until a callback that
 we’re still waiting on.
How callbacks are handled —
1. At the exact spot a callback is passed to
 its async function, we create a “future”
 buffer.

2. We continue executing the template,
 flushing everything up until a callback that
 we’re still waiting on.

3. When each callback returns, we fill in its
 buffer and continue flushing down the page
 as we can.
JS Compatibility —
Should be mostly complete, can
correctly compile embedded jQuery
and underscore.js source already.
(no they aren’t templates, but they are complex JS)
What about
performance? —
What about
performance? —
Parses ~40-50,000 lines/sec uncached.
Good, not great (should improve).
What about
performance? —
Parses ~40-50,000 lines/sec uncached.
Good, not great (should improve).

But AJS can render while Node
waits on your DB calls, and page
loads will feel faster because
<head> resources aren’t blocked.
Current limitations —
Current limitations —
1. Since callbacks are detected and at runtime,
 callbacks can’t be nested. There may be
 some ways around this, but we may not want
 to encourage it...
Current limitations —
1. Since callbacks are detected and at runtime,
 callbacks can’t be nested. There may be
 some ways around this, but we may not want
 to encourage it...

2. There’s no layout nesting built into the
 middleware.
Current limitations —
1. Since callbacks are detected and at runtime,
 callbacks can’t be nested. There may be
 some ways around this, but we may not want
 to encourage it...

2. There’s no layout nesting built into the
 middleware.

3. Others...
My inspiration —




Your welcome, Ryan.
How to get it —
1 - npm install ajs
2 - github.com/kainosnoema/ajs

Submit issues, fork and improve!

More Related Content

PDF
Bottleneck in Elixir Application - Alexey Osipenko
PDF
Introduction to REST API with Node.js
PDF
A first look into the Project Loom in Java
PDF
Stop JavaScripting like it's 1999
ODP
MySQL::Replication (Melbourne Perl Mongers 2011-07)
PDF
Starting a new ruby on rails development
PDF
The SPDY Protocol
PPTX
Introduction to node.js
Bottleneck in Elixir Application - Alexey Osipenko
Introduction to REST API with Node.js
A first look into the Project Loom in Java
Stop JavaScripting like it's 1999
MySQL::Replication (Melbourne Perl Mongers 2011-07)
Starting a new ruby on rails development
The SPDY Protocol
Introduction to node.js

What's hot (8)

PDF
Server Side Apocalypse, JS
PDF
ConvergeSE: We Will All Be Game Developers
PDF
Node.js: Whats the Big Deal? Presented and JS Meetup Chicago
PDF
下吧开发总结
PDF
Async programming with Observable
PPTX
Node presentation
PDF
Java/Spring과 Node.js의 공존 시즌2
KEY
Smalltalk in the pocket - Building applications for the iPhone
Server Side Apocalypse, JS
ConvergeSE: We Will All Be Game Developers
Node.js: Whats the Big Deal? Presented and JS Meetup Chicago
下吧开发总结
Async programming with Observable
Node presentation
Java/Spring과 Node.js의 공존 시즌2
Smalltalk in the pocket - Building applications for the iPhone
Ad

Similar to AJS — Asynchronous Templating in Node (20)

PPTX
Asynchronous programming - .NET Way
PDF
Xtext beyond the defaults - how to tackle performance problems
PDF
Hippo get together presentation solr integration
KEY
Work Queues
KEY
Gearman and CodeIgniter
KEY
Asynchronous Awesome
PDF
Updates on Offline: “My AppCache won’t come back” and “ServiceWorker Tricks ...
PPTX
Ups and downs of enterprise Java app in a research setting
KEY
Site Performance - From Pinto to Ferrari
PDF
ABRIDGED VERSION - Joys & frustrations of putting 34,000 lines of Haskell in...
PDF
The art of concurrent programming
PPTX
Real time analytics using Hadoop and Elasticsearch
PPTX
Search and analyze your data with elasticsearch
PDF
Debugging ansible modules
PDF
Ruby thread safety first
PDF
Need for Async: Hot pursuit for scalable applications
PDF
Building Asynchronous Applications
KEY
Ruby on Rails survival guide of an aged Java developer
PPTX
Zero ETL analytics with LLAP in Azure HDInsight
PPT
Parallel Programming: Beyond the Critical Section
Asynchronous programming - .NET Way
Xtext beyond the defaults - how to tackle performance problems
Hippo get together presentation solr integration
Work Queues
Gearman and CodeIgniter
Asynchronous Awesome
Updates on Offline: “My AppCache won’t come back” and “ServiceWorker Tricks ...
Ups and downs of enterprise Java app in a research setting
Site Performance - From Pinto to Ferrari
ABRIDGED VERSION - Joys & frustrations of putting 34,000 lines of Haskell in...
The art of concurrent programming
Real time analytics using Hadoop and Elasticsearch
Search and analyze your data with elasticsearch
Debugging ansible modules
Ruby thread safety first
Need for Async: Hot pursuit for scalable applications
Building Asynchronous Applications
Ruby on Rails survival guide of an aged Java developer
Zero ETL analytics with LLAP in Azure HDInsight
Parallel Programming: Beyond the Critical Section
Ad

AJS — Asynchronous Templating in Node

  • 1. AJS: Asynchronous Templating in Node (completing the async puzzle)
  • 2. Who am I? Evan Owen Senior Developer @ LifeKraze Lover of Ruby, JS, Redis, good design and asynchronous code.
  • 3. History of Templating Old-school PHP: the template == your app
  • 4. History of Templating Old-school PHP: the template == your app already flushed
  • 5. History of Templating Old-school PHP: the template == your app already flushed blocking
  • 6. OO PHP + template == worse
  • 7. OO PHP + template == worse blocking
  • 8. OO PHP + template == worse blocking nothing flushed!
  • 9. Ruby + ERB template == just as bad
  • 10. Ruby + ERB template == just as bad blocking
  • 11. Ruby + ERB template == just as bad blocking nothing flushed!
  • 12. Rails 3.1 Automatic Flushing == better
  • 13. Rails 3.1 Automatic Flushing == better <head> flushed
  • 14. Rails 3.1 Automatic Flushing == better <head> flushed still blocking
  • 15. Rails 3.1 Automatic Flushing == better <head> flushed still blocking other db calls must wait
  • 16. What about Node? It’s non-blocking, right? WRONG. Node will block (per-request) at your first blocking function.
  • 17. Node + EJS == not enough
  • 18. Node + EJS == not enough non-blocking
  • 19. Node + EJS == not enough non-blocking non-blocking
  • 20. Node + EJS == not enough non-blocking non-blocking blocking!
  • 21. Node + existing async libs == frustrating node-asyncEJS
  • 22. Node + existing async libs == frustrating node-asyncEJS things to worry about
  • 23. Node + existing async libs == frustrating nun
  • 24. Node + existing async libs == frustrating nun more things to worry about
  • 25. Node + existing async libs == frustrating nun more things to worry about no logic allowed, loops are hard
  • 27. What we need — 1. Familiar, standard syntax
  • 28. What we need — 1. Familiar, standard syntax 2. Nothing extra to learn or think about
  • 29. What we need — 1. Familiar, standard syntax 2. Nothing extra to learn or think about 3. Completely non-blocking, able to continue rendering while waiting for callbacks
  • 30. What we need — 1. Familiar, standard syntax 2. Nothing extra to learn or think about 3. Completely non-blocking, able to continue rendering while waiting for callbacks 4. Fast
  • 31. Node + AJS == async, easy
  • 32. Node + AJS == async, easy superset of JS (similar to EJS)
  • 33. Node + AJS == async, easy superset of JS (similar to EJS) use callbacks naturally (can/should be defined in controller)
  • 34. Node + AJS == async, easy superset of JS (similar to EJS) use callbacks naturally (can/should be defined in controller) include partials
  • 36. How AJS works — 1. Parse source to an abstract syntax tree (AST)
  • 37. How AJS works — 1. Parse source to an abstract syntax tree (AST) 2. Add “futures” hooks around callbacks
  • 38. How AJS works — 1. Parse source to an abstract syntax tree (AST) 2. Add “futures” hooks around callbacks 3. Recompile and cache optimized JS
  • 39. How AJS works — 1. Parse source to an abstract syntax tree (AST) 2. Add “futures” hooks around callbacks 3. Recompile and cache optimized JS 4. Execute code inside a VM that manages and handles async callbacks
  • 40. How callbacks are handled —
  • 41. How callbacks are handled — 1. At the exact spot a callback is passed to its async function, we create a “future” buffer.
  • 42. How callbacks are handled — 1. At the exact spot a callback is passed to its async function, we create a “future” buffer. 2. We continue executing the template, flushing everything up until a callback that we’re still waiting on.
  • 43. How callbacks are handled — 1. At the exact spot a callback is passed to its async function, we create a “future” buffer. 2. We continue executing the template, flushing everything up until a callback that we’re still waiting on. 3. When each callback returns, we fill in its buffer and continue flushing down the page as we can.
  • 44. JS Compatibility — Should be mostly complete, can correctly compile embedded jQuery and underscore.js source already. (no they aren’t templates, but they are complex JS)
  • 46. What about performance? — Parses ~40-50,000 lines/sec uncached. Good, not great (should improve).
  • 47. What about performance? — Parses ~40-50,000 lines/sec uncached. Good, not great (should improve). But AJS can render while Node waits on your DB calls, and page loads will feel faster because <head> resources aren’t blocked.
  • 49. Current limitations — 1. Since callbacks are detected and at runtime, callbacks can’t be nested. There may be some ways around this, but we may not want to encourage it...
  • 50. Current limitations — 1. Since callbacks are detected and at runtime, callbacks can’t be nested. There may be some ways around this, but we may not want to encourage it... 2. There’s no layout nesting built into the middleware.
  • 51. Current limitations — 1. Since callbacks are detected and at runtime, callbacks can’t be nested. There may be some ways around this, but we may not want to encourage it... 2. There’s no layout nesting built into the middleware. 3. Others...
  • 52. My inspiration — Your welcome, Ryan.
  • 53. How to get it — 1 - npm install ajs 2 - github.com/kainosnoema/ajs Submit issues, fork and improve!

Editor's Notes

  • #2: \n
  • #3: \n
  • #4: We haven&amp;#x2019;t progressed since the days of inline PHP, in fact we&amp;#x2019;ve regressed\n Node&amp;#x2019;s non-blocking architecture is being handicapped by archaic templating conventions\n We need something completely new (at least under the hood)\n
  • #5: We haven&amp;#x2019;t progressed since the days of inline PHP, in fact we&amp;#x2019;ve regressed\n Node&amp;#x2019;s non-blocking architecture is being handicapped by archaic templating conventions\n We need something completely new (at least under the hood)\n
  • #6: \n
  • #7: \n
  • #8: \n
  • #9: \n
  • #10: From the end user&amp;#x2019;s perspective, we&amp;#x2019;re finally back the experience we had with inline PHP.\nRegardless, we&amp;#x2019;re stuck with Ruby&amp;#x2019;s blocking IO calls. \n
  • #11: From the end user&amp;#x2019;s perspective, we&amp;#x2019;re finally back the experience we had with inline PHP.\nRegardless, we&amp;#x2019;re stuck with Ruby&amp;#x2019;s blocking IO calls. \n
  • #12: From the end user&amp;#x2019;s perspective, we&amp;#x2019;re finally back the experience we had with inline PHP.\nRegardless, we&amp;#x2019;re stuck with Ruby&amp;#x2019;s blocking IO calls. \n
  • #13: Somehow we have this assumption that whatever we write in Node will be non-blocking.\nUnfortunately this isn&amp;#x2019;t true on a per-request level... if you have a blocking function, Node blocks.\n
  • #14: \n
  • #15: \n
  • #16: \n
  • #17: \n
  • #18: \n
  • #19: \n
  • #20: \n
  • #21: \n
  • #22: \n
  • #23: \n
  • #24: \n
  • #25: \n
  • #26: \n
  • #27: \n
  • #28: \n
  • #29: \n
  • #30: \n
  • #31: \n
  • #32: \n
  • #33: \n
  • #34: \n
  • #35: The uncached performance is only relevant on the first page load.\nAfter that performance is MUCH better, and will only improve.\n
  • #36: The uncached performance is only relevant on the first page load.\nAfter that performance is MUCH better, and will only improve.\n
  • #37: 2. Thought of this last night actually...\n
  • #38: 2. Thought of this last night actually...\n
  • #39: 2. Thought of this last night actually...\n
  • #40: Obviously Ryan was joking around, but in threory AJS could be used as\nan asynchronous &amp;#x201C;PHP&amp;#x201D; by simply serving up AJS files, mapping URIs\nto a directory structure. Not that you&amp;#x2019;d want to.\n
  • #41: \n