{ dust.js } at LinkedIn     Yevgeniy Brikman
2011: LinkedIn adopted dust.js, a client side templating language
This is the story of client sidetemplating at massive scale
Dust in the wild                   Profile 2.0
Dust in the wild             People You May Know
Dust in the wild                   Influencers
About me                Presentation Infrastructure Team   (also Hackdays, [in]cubator, Engineering Blog, Open Source)
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
LinkedIn in 2003 A single, monolithic webapp: servlets/JSPs
LinkedIn in 2010 New web frameworks to boost productivity:  Grails/GSPs, JRuby/ERBs, plus others
Fragmentation● Each tech stack used a different templating  technology (JSP, GSP, ERB, etc)● No easy way to share UI code ...
We needed to unify the view layer
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
We began looking at client side    templating solutions
Traditional server side rendering    All page content is rendered as HTML and sent to the browser
Client side rendering (simplified)   Server sends JSON. The template is fetched from the CDN and                      rend...
Client side rendering (full)   Server sends JSON embedded in an HTML skeleton. The skeleton      has JavaScript code that ...
Client side MVC   Client side MVC makes client side rendering even more important.
Client side rendering (with MVC)   Once a page has loaded, the client side MVC takes over, fetching   JSON from the server...
Client side rendering benefits● DRY: works with any server side stack plus  client side● Performance: bandwidth, latency, ...
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
Decisions, decisions   We evaluated 26 different options. They tended to fall into one of        two groups: Embedded Java...
Embedded JavaScript Templates <ul>   <% for(var i = 0; i < supplies.length; i ++) { %>      <li><%= supplies[i] %> </li>  ...
Embedded JavaScript Templates●   underscore.js●   Jade●   haml-js●   jQote2●   doT●   Stencil●   Parrot●   Eco●   EJS●   j...
Logic-less Templates <p>   Hello {name}! You have {count} new messages. </p>              Custom template language that li...
Embedded JavaScript Templates●   mustache●   dust.js●   handlebars●   Google Closure Templates●   Nun●   Mu●   kite
The test           Render a simplified LinkedIn profile
The rules● Produce this HTML output● Use this profile JSON as input● The same template should render on the server-side  a...
The criteria●   DRY●   i18n●   Hot reload●   Performance●   Ramp-up time●   Ramped-up productivity●   Server/client suppor...
Criteria are just guidelines;not all are weighted equally.
The finalists
Google Closure TemplatesPros ● Templates are compiled into JavaScript for client-side and Java for server-    side. ● Good...
MustachePros ● Very popular choice with a large, active community. ● Server side support in many languages, including Java...
HandlebarsPros ● Logic-less templates do a great job of forcing you to separate presentation    from logic. ● Clean syntax...
Dust.jsPros ● Logic-less templates do a great job of forcing you to separate presentation    from logic. ● Clean syntax le...
Spoiler alert!
dust.js won
Takeaways● Based on how we weighed our criteria, Dust  fit our needs the best● Use real use cases and identify the most  i...
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
The LinkedIn Fork● The original maintainer abandoned dust● The LinkedIn fork is now the most active● Weve added bug fixes,...
Try it out● Homepage:  http://linkedin.github.com/dustjs/● Try it in the browser: http://linkedin.github.  com/dustjs/test...
(demo)
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
How do you handle view logic?
Yes, there is such a thing as view logic and its separate from business logic
ComplicatedLogic      logicLogic
Homework assignment: implement  this view with a truly logic-less template (no helpers/lambdas!)
Helpers to the rescue: @eq, @ne {@eq key="foo" value="foo"}The key and value are equal!{/ eq} {@ne key="foo" value="bar"}T...
Helpers to the rescue: @gt, @lt  {@gt key="22" value="3"}22 is greater than 3{/ gt}  {@lt key="0" value="500"}0 is less th...
Helpers to the rescue: @select {@select key=age}   {@eq value="1"}Baby{/eq}   {@lt value="10"}Child{/lt}   {@lt value="18"...
Helpers to the rescue: @size, @math You have {@ size key=list/} new messages {@math key="16" method="add" operand="4"/}
Full library of helpers is available at:https://github.com/linkedin/dustjs-helpers
How do we handled clients without JavaScript? What about SEO?
SSR: Server Side Rendering● Google V8 engine● A plugin for Apache Traffic Server● Executes arbitrary JavaScript server sid...
Client side rendering (full, SSR)   The HTML Skeleton is written in dust. SSR renders it as HTML.
SSR uses● Render dust skeleton into HTML skeleton● Render everything server side for:  ○ Crawlers/bots/search engines  ○ C...
What about i18n? Formatting? URLs?
Server side templates <p>   <a href="${url.link( home-page }">$!{i18n(hello-world )}</a> </p>    In JSPs, Java libraries d...
Sending an entire i18n dictionary,URL dictionary, and all formattingcode to the browser is expensive
Option #1: everything server sideJava controller     json.put("name", "Jim");     json.put("home-page-link" , Url.link("ho...
Option #1: everything server sidePros● Simple, easy to understand● Clean templatesCons● Controller code cluttered with vie...
Option #2: dynamic pre-processingOriginal profile-page dust template     <p>       <a href="{@pre.link key="home-page"}   ...
Option #2: dynamic pre-processingJava controller     json.put("name", "Jim");     render("profile-page" , json);Pre-proces...
Option #2: dynamic pre-processingPros● All view logic is in the templates● Clean server side codeCons● Complicated, hard t...
Option #3: static pre-processingOriginal profile-page dust template     <p>       <a href="{home-page-link}">{@i18n}Hello ...
Option #3: static pre-processingPros● Hybrid approach: i18n is in the templates,  only formatting/link generation is in co...
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
LinkedIn in 2013 We now many services using client side rendering and         many using server-side rendering
A full rewrite is too expensive
Fizzy: Composable UI
Fizzy Fizzy is an ATS plugin that reads the HTML (skeleton or                full) returned by webapps
Fizzy <html>   <body>     <h1>Composable UI </h1>     <script type="fs/embed" fs-uri="/news-feed/top" ></script>     <scri...
Fizzy                    HTML skeleton                                    Embed                        Embed              ...
Deferred rendering
Typical page               HTML Skeleton                                     Dust                                   templa...
Typical page                        HTML Skeleton                                              Dust                       ...
Typical page                       HTML Skeleton                                             Dust                         ...
Deferred rendering● Dramatically improve performance by not  rendering anything below the fold● Improve it even further by...
Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust...
Final thoughts● Dust.js has improved developer productivity and code  sharing at LinkedIn● Client side templating offers p...
Questions?
Upcoming SlideShare
Loading in...5
×

Dust.js

32,640

Published on

In 2011, LinkedIn adopted dust.js. This is the story of client side templating at massive scale.

Published in: Technology
0 Comments
55 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
32,640
On Slideshare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
225
Comments
0
Likes
55
Embeds 0
No embeds

No notes for slide

Dust.js

  1. 1. { dust.js } at LinkedIn Yevgeniy Brikman
  2. 2. 2011: LinkedIn adopted dust.js, a client side templating language
  3. 3. This is the story of client sidetemplating at massive scale
  4. 4. Dust in the wild Profile 2.0
  5. 5. Dust in the wild People You May Know
  6. 6. Dust in the wild Influencers
  7. 7. About me Presentation Infrastructure Team (also Hackdays, [in]cubator, Engineering Blog, Open Source)
  8. 8. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  9. 9. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  10. 10. LinkedIn in 2003 A single, monolithic webapp: servlets/JSPs
  11. 11. LinkedIn in 2010 New web frameworks to boost productivity: Grails/GSPs, JRuby/ERBs, plus others
  12. 12. Fragmentation● Each tech stack used a different templating technology (JSP, GSP, ERB, etc)● No easy way to share UI code for common components (e.g. profile, the feed)● The "global" nav had to be rewritten in multiple languages/technologies. Updating it was very time consuming.
  13. 13. We needed to unify the view layer
  14. 14. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  15. 15. We began looking at client side templating solutions
  16. 16. Traditional server side rendering All page content is rendered as HTML and sent to the browser
  17. 17. Client side rendering (simplified) Server sends JSON. The template is fetched from the CDN and rendered in browser.
  18. 18. Client side rendering (full) Server sends JSON embedded in an HTML skeleton. The skeleton has JavaScript code that fetches and renders the template.
  19. 19. Client side MVC Client side MVC makes client side rendering even more important.
  20. 20. Client side rendering (with MVC) Once a page has loaded, the client side MVC takes over, fetching JSON from the server and rendering it with client side templates
  21. 21. Client side rendering benefits● DRY: works with any server side stack plus client side● Performance: bandwidth, latency, caching● Productivity: fast iteration, mock JSON● Rich apps: client side MVC
  22. 22. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  23. 23. Decisions, decisions We evaluated 26 different options. They tended to fall into one of two groups: Embedded JavaScript and Logic Less.
  24. 24. Embedded JavaScript Templates <ul> <% for(var i = 0; i < supplies.length; i ++) { %> <li><%= supplies[i] %> </li> <% } %> </ul> Normal JavaScript code directly in the template.
  25. 25. Embedded JavaScript Templates● underscore.js● Jade● haml-js● jQote2● doT● Stencil● Parrot● Eco● EJS● jQuery templates● node-asyncEJS
  26. 26. Logic-less Templates <p> Hello {name}! You have {count} new messages. </p> Custom template language that limits logic
  27. 27. Embedded JavaScript Templates● mustache● dust.js● handlebars● Google Closure Templates● Nun● Mu● kite
  28. 28. The test Render a simplified LinkedIn profile
  29. 29. The rules● Produce this HTML output● Use this profile JSON as input● The same template should render on the server-side and client-side● Properly handle profile data display rules● Format numbers and dates correctly
  30. 30. The criteria● DRY● i18n● Hot reload● Performance● Ramp-up time● Ramped-up productivity● Server/client support● Community● Library agnostic● Testable● Debuggable● Editor support● Maturity● Documentation● Code documentation
  31. 31. Criteria are just guidelines;not all are weighted equally.
  32. 32. The finalists
  33. 33. Google Closure TemplatesPros ● Templates are compiled into JavaScript for client-side and Java for server- side. ● Good built-in functionality: loops, conditionals, partials, i18n. ● Documentation is enforced by the template.Cons ● Very little usage outside of Google. No plans to push new versions or accept new contributions. ● Some functionality is missing, such as being able to loop over maps. ● Not DRY: adding new functionality requires implementing plugins in both Java and JavaScript.
  34. 34. MustachePros ● Very popular choice with a large, active community. ● Server side support in many languages, including Java. ● Logic-less templates do a great job of forcing you to separate presentation from logic. ● Clean syntax leads to templates that are easy to build, read, and maintain.Cons ● A little too logic-less: basic tasks (e.g. label alternate rows with different CSS classes) are difficult. ● View logic is often pushed back to the server or implemented as a "lambda" (callable function). ● For lambdas to work on client and server, you must write them in JavaScript. ● Slow, interpreted templates
  35. 35. HandlebarsPros ● Logic-less templates do a great job of forcing you to separate presentation from logic. ● Clean syntax leads to templates that are easy to build, read, and maintain. ● Compiled rather than interpreted templates. ● Better support for paths than mustache (ie, reaching deep into a context object). ● Better support for global helpers than mustache.Cons ● Requires server-side JavaScript to render on the server.
  36. 36. Dust.jsPros ● Logic-less templates do a great job of forcing you to separate presentation from logic. ● Clean syntax leads to templates that are easy to build, read, and maintain. ● Compiled rather than interpreted templates. ● Better support for paths than mustache (ie, reaching deep into a context object). ● Better support for global helpers than mustache. ● Inline parameters. ● Blocks & inline partials. ● Overriding contexts. ● Support for asynchronous rendering and streaming. ● Composable templates.Cons ● Requires server-side JavaScript to render on the server. ● Maintainer of github repo is not responsive.
  37. 37. Spoiler alert!
  38. 38. dust.js won
  39. 39. Takeaways● Based on how we weighed our criteria, Dust fit our needs the best● Use real use cases and identify the most important criteria to you● For non-trivial views, no templating option works on client and server, unless your server executes JavaScript (v8, Rhino)
  40. 40. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  41. 41. The LinkedIn Fork● The original maintainer abandoned dust● The LinkedIn fork is now the most active● Weve added bug fixes, perf improvements, and helpers
  42. 42. Try it out● Homepage: http://linkedin.github.com/dustjs/● Try it in the browser: http://linkedin.github. com/dustjs/test/test.html● Source code: https://github. com/linkedin/dustjs
  43. 43. (demo)
  44. 44. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  45. 45. How do you handle view logic?
  46. 46. Yes, there is such a thing as view logic and its separate from business logic
  47. 47. ComplicatedLogic logicLogic
  48. 48. Homework assignment: implement this view with a truly logic-less template (no helpers/lambdas!)
  49. 49. Helpers to the rescue: @eq, @ne {@eq key="foo" value="foo"}The key and value are equal!{/ eq} {@ne key="foo" value="bar"}The key and value are not equal!{/ ne}
  50. 50. Helpers to the rescue: @gt, @lt {@gt key="22" value="3"}22 is greater than 3{/ gt} {@lt key="0" value="500"}0 is less than 500{/ lt}
  51. 51. Helpers to the rescue: @select {@select key=age} {@eq value="1"}Baby{/eq} {@lt value="10"}Child{/lt} {@lt value="18"}Teen{/lt} {@default}Adult{/default} {/select}
  52. 52. Helpers to the rescue: @size, @math You have {@ size key=list/} new messages {@math key="16" method="add" operand="4"/}
  53. 53. Full library of helpers is available at:https://github.com/linkedin/dustjs-helpers
  54. 54. How do we handled clients without JavaScript? What about SEO?
  55. 55. SSR: Server Side Rendering● Google V8 engine● A plugin for Apache Traffic Server● Executes arbitrary JavaScript server side, including rendering dust templates● Often nicknamed Unified Server Side Rendering... aka, USSR
  56. 56. Client side rendering (full, SSR) The HTML Skeleton is written in dust. SSR renders it as HTML.
  57. 57. SSR uses● Render dust skeleton into HTML skeleton● Render everything server side for: ○ Crawlers/bots/search engines ○ Clients without JavaScript ○ Slow clients (IE < 8)● Logic less templates help ensure that everything renders correctly server-side. No DOM dependencies!
  58. 58. What about i18n? Formatting? URLs?
  59. 59. Server side templates <p> <a href="${url.link( home-page }">$!{i18n(hello-world )}</a> </p> In JSPs, Java libraries did i18n, text formatting, URL generation
  60. 60. Sending an entire i18n dictionary,URL dictionary, and all formattingcode to the browser is expensive
  61. 61. Option #1: everything server sideJava controller json.put("name", "Jim"); json.put("home-page-link" , Url.link("home-page" )); json.put("hello-world-text" , I18n.get("hello-world" )); render("profile-page" , json);profile-page dust template <p> <a href="{home-page-link} ">{hello-world-text} </a> </p> All i18n, text formatting, and URL generation is done server side and added to the JSON payload
  62. 62. Option #1: everything server sidePros● Simple, easy to understand● Clean templatesCons● Controller code cluttered with view logic
  63. 63. Option #2: dynamic pre-processingOriginal profile-page dust template <p> <a href="{@pre.link key="home-page"} ">{@pre.i18n key="hello-world"} </a> </p>Pre-processed profile-page dust template <p> <a href="{link-123}">{i18n-456}</a> </p> Step 1: the @pre helper tags get replaced at build time with references to unique keys in the JSON
  64. 64. Option #2: dynamic pre-processingJava controller json.put("name", "Jim"); render("profile-page" , json);Pre-processed JSON { "name": "Jim", "link-123" : "http://www.linkedin.com" , "i18n-456" : "Hello World" } Step 2: whenever profile-page is rendered, automatically "enhance" the JSON with the requested i18n and URL values
  65. 65. Option #2: dynamic pre-processingPros● All view logic is in the templates● Clean server side codeCons● Complicated, hard to debug● Tight coupling: need special server and build logic to use templates● Performance: increased JSON payload and/or more server processing time
  66. 66. Option #3: static pre-processingOriginal profile-page dust template <p> <a href="{home-page-link}">{@i18n}Hello World{/i18n}</a> </p>Pre-processed profile-page dust template (one per language) <p> <a href="{home-page-link}">Hello World</a> </p> <p> <a href="{home-page-link}">Bonjour monde</a> </p> Generate one template per language with translated text already filled in. Link generation and formatting still happen server-side.
  67. 67. Option #3: static pre-processingPros● Hybrid approach: i18n is in the templates, only formatting/link generation is in controller● Simpler, easier to debug than dynamic pre- processingCons● Custom build process● Increased template payload, but i18n strings now cached with template
  68. 68. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  69. 69. LinkedIn in 2013 We now many services using client side rendering and many using server-side rendering
  70. 70. A full rewrite is too expensive
  71. 71. Fizzy: Composable UI
  72. 72. Fizzy Fizzy is an ATS plugin that reads the HTML (skeleton or full) returned by webapps
  73. 73. Fizzy <html> <body> <h1>Composable UI </h1> <script type="fs/embed" fs-uri="/news-feed/top" ></script> <script type="fs/embed" fs-uri="/pymk"></script> <script type="fs/embed" fs-uri="/ad"></script> </body> </html> If Fizzy finds an fs/embed in the HTML, it calls the URI and injects the response into the page.
  74. 74. Fizzy HTML skeleton Embed Embed EmbedA page now consists of a skeleton with a bunch of Fizzy- processed embeds.
  75. 75. Deferred rendering
  76. 76. Typical page HTML Skeleton Dust template Dust template Dust template Dust template Dust template Dust template
  77. 77. Typical page HTML Skeleton Dust template Dust template Dust The fold template Dust template Dust template Dust template On initial page load, the user doesnt see anything below the fold
  78. 78. Typical page HTML Skeleton Dust template Dust template Dust The fold template Dust template Dust templateNo needto render Dust template No need to fetch data or render
  79. 79. Deferred rendering● Dramatically improve performance by not rendering anything below the fold● Improve it even further by not fetching the data for things far out of view● The challenge: the fold is at different positions on different devices
  80. 80. Outline1. A little LinkedIn history2. A new direction: client side rendering3. Picking a templating technology4. Take dust for a spin5. Challenges: SEO, i18n, logic6. The Future
  81. 81. Final thoughts● Dust.js has improved developer productivity and code sharing at LinkedIn● Client side templating offers powerful new capabilities and benefits● It also introduces tough new challenges● Its an evolving technology; now is a good time to get involved
  82. 82. Questions?
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×