Client v. Server Templating Shootout
By Ryan Florence, published 2012-06-18
There’s some debate about this question: Is it better to have the server render the HTML for you, or for the browser to render the HTML from JSON data?
What This is NOT Comparing
This test is about user-interactions that send off an xhr and return HTML or JSON. This is not about how quickly you can render content on an initial page load.
Client-side Templating is Faster (probably…)
At least in every browser/connection I could get my hands on (except running the test locally). Don’t take my word for it, run the test in IE6, IE7, or an android phone for the crappiest scenarios.
What the Result Labels Mean
|server render||Time to innerHTML the element with the html response|
|client render||Time to parse the JSON string and send it through a pre-compiled Handlebars template, then innerHTML the element.|
|server response||How long it takes the xhr request to return (time for the server to render the HTML and the browser to download it)|
|client response||How long it takes the json request to return the data (time for the server to produce the json and the browser to download it)|
|server total||Time from the html request to a fully rendered element|
|client total||Time from the json request to a fully rendered element|
|client parseJSON||Time for the browser to translate the JSON response to a JSON object.|
Is This a Fair Test?
I think so. You can go look at the code yourself on github and decide if its fair. The ERB and Handlebars templates are identical. They both handle the iteration and both render a partial template. There are 100 records being fetched each time, same action is being requested, etc. If you find some flawed part of the test, let me know. I messed around with the size of each record and the number of records return and client-side was always faster.
Why Is Client-side Faster?
But first, there are 2 (3ish) things that are slower when using the client to render the HTML.
- The browser has to parse the JSON response string into an object
- The browser has to generate an HTML string from the parsed JSON
- The server has to create a JSON string instead of an HTML string which is unfortunately more expensive in rails (?) but I can’t speak for other backends.
So why is client-side rendering faster?
Every time the server sends HTML it sends the data and the template.
parseJSON and throwing the result at the Handlebars function).
Next time you say “client-side templating is slow”, make sure you have an extreme definition of slow.
Its notable that returning JSON or HTML is irrelevant for the things you can do on the server (like caching) to speed up your apps performance.
But Server-side is Faster When…
The data in this test is contrived, that’s why I didn’t gzip. I assumed that JSON is going to gzip as well or better than HTML, but I realize now I could be completely wrong. If the HTML gzips smaller than the JSON, then sending HTML is going to be faster overall. I hope to find some time soon to use real data with gzipping.
Other Benefits to Client-side Templating
Besides being faster (in this test), building your frontend on top of a JSON API has these benefits:
- You can test the frontend without a backend (devs are less dependent on each other’s code).
- You can reuse API endpoints for different UI (instead of being tied down to the HTML or creating a new end-point).
- You can mock server data for faster prototypes.
- You can change your backend incrementally or completely without the frontend even knowing (the growing up cycle is something like: node -> rails -> scala, amirite?)
- Your API gets much better (great for third-party integrations and mobile apps)
Do Whatchoo Want
I’d never say you’re doing it wrong if you send HTML in your xhr. Its awfully convenient and may very well be a better development experience for some.
If performance is your ultimate goal then use the method that creates the smallest gzipped download. Otherwise, use what you like best.
Check Out My Results
Here are screen shots from pretty much every browser I had quick access to (even IE6) making 100 requests. Sorry for the blatant disregard for design here.
iPhone 3G on the Edge Network
iPhone 4 wifi