Close and Go BackBack to Viget

Benchmarking Javascript Templating Libraries

Brian Landau
Brian Landau, Web Developer, December 08, 2009 13

Because of Connect-a-Sketch’s heavy use of Javascript, I’m always looking for new ways to improve JS performance. This is, of course, important for ensuring a good user experience on as many machines as possible, not just those with newer computers and browsers. But, it’s also important for our ability to add new features as new features often mean more javascript running on the page.

One part of that Javascript functionality is generating the HTML for page nodes (representations of pages on the canvas). I use one of the many javascript templating libraries to do this currently. I recently noticed that mustache.js had been released and I got interested in exploring what other options are out there and how well they perform.

Methodology

I gathered up a huge list (the only requirement being that it be independent of other libraries or be a jQuery plugin) and narrowed it down to ones with template and API syntax I liked and code that looked at the very least decent on a quick glance. Following that, I created a series of benchmark pages that I would use to test the speed of each library. I generally had two tests, a simple test of a basic HTML template, and a test where I wanted to iterate over some data. Some of the libraries had support for iterating within the template syntax and others that didn’t; for those that didn’t I iterated via a standard for loop appending the content to the end of the relevant HTML element. A couple of the libraries (underscore and Tempest) offer the ability to compile the template into a function, for these I also created a third test for that functionality.

The libraries I ended up testing were:

Following that, I created a jQuery benchmark function based on PPK’s benchmarking methodology. I would load the page and then call the benchmark function, passing in the benchmark test function, from Safari’s Javascript console. Each test function was benchmarked over 1000 iterations, and each benchmark was run 5 times. The results from the 5 runs were averaged and used to produce the results below.

Results

Generally speaking, the standard test performed slightly more quickly than the loop test, the exception being those libraries that didn’t have iterating functionality built-in, in which case the loop test took significantly longer. Overall this within-library difference is what we’d expect. Overall though, all of the libraries actually performed relatively the same.

image

Assuming you want to be able to handle iterations within the template the fastest library was mustache.js, followed by Srender and underscore. Although the three libraries that didn’t handle iterations performed badly on the loop test, they actually performed best on the simple test with the nano library performing best overall.

image

When comparing the simple test to the compiled test it seems compiling doesn’t offer much of performance benefit, although it seemed to offer more benefit for the underscore library then for Tempest.

Take your pick

In the end it seems like they were all reasonable choices, leading me to believe most of the other options out there probably generally perform about equally. Which you choose to go with probably depends on whether or not what you’re templating will be iterating over a set of data or not. If it is, you probably would want to go with mustache.js; if not probably nano.

Resources

I’ve put up a repository containing the libraries and HTML benchmark pages, as well as a gist of the benchmarking function.

I’ve also put the original data and summary data into a gist.

Update:
The author of the Tempest library, Nick Fitzgerald, contacted me to let me know that Tempest does not turn templates into pre-compiled functions. However, it does cache the template string. To everyone, sorry about that mixup.

Wynn Netherland said on 12/08 at 04:18 PM

You TOTALLY stole my next blog post idea, but I’m glad you did. I hadn’t seen a couple of these options. Aside from speed, do you have a preference on syntax, binding style?

Gk said on 12/08 at 09:46 PM

how about jaml? http://github.com/edspencer/jaml

Justin said on 12/08 at 10:24 PM

What about EJS?

Andy said on 12/09 at 01:07 AM

Hm your github repo doesn’t work for me.  I’m just serving the *benchmark.html pages to my browser and nothing happens.  How do you get it to work?

Mic said on 12/09 at 04:58 AM

You didn’t like PURE ? ;) ... http://github.com/pure/pure
It works with most common JS libs and as a jquery plugin.

Arnout said on 12/09 at 06:08 AM

I wonder how much it compares to the Adobe Spry library that is heavily focused on data handling. labs.adobe.com/technologies/spry/

Brian Landau said on 12/10 at 11:13 AM

@Gk, @Justin, and @ Mic - I’ll have to look at all of those and consider benchmarking them too. Thanks!

@Wynn - Great minds think alike! Not sure what you mean by binding style, but for syntax I prefer those that use curly braces personally versus “<%” notation. But it’s not a strong preference.

@Andy - You have to open up the page and then open up your browsers JS console, in Safari this is available in the web inspector, in Firefox you can use Firebug. I’m not sure how you would do it in IE or Opera. Once in the console there’s a function you run, something like:

$.benchmark(1000, ‘#simple_test’, $.benchmarks.test_simple);
Jan Lehnardt said on 12/11 at 10:01 AM

Hi Brian,

great post. Super happy to see Mustache.js coming out so fast. We haven’t even done any performance work yet :)

Cheers
Jan
--

Francisco Tolmasky said on 12/11 at 03:21 PM

I would like to second the request for the inclusion of PURE to this

TJ Holowaychuk said on 12/11 at 07:06 PM

mustache.js is very slow… the implementation is pretty “meh”. If you pre-compile the templates it is a HUGE saving, check out mojo github.com/visionmedia/mojo

Mic said on 12/12 at 07:00 PM

@Brian,
I’ve tried your tests with PURE (on Mac OSX - Safari, FF, Chrome, Opera).
And PURE is faster than mustache on the loop test!
Ahem… ok ;)… I added some more data to the loop (ie: 30 records instead of 5).
With 5 records mustache is faster.

To be sure of what we measure, I think a benchmark should be based on some real world examples of rendering.
And then, while raw speed is a key ingredient, I don’t think it’s the only one to promote.

Here below are the modified pages I used to test.
There are some additional links to run the test instead of the console, as it can pollute speed measurement I guess.

mustache: http://gist.github.com/255096
PURE: http://gist.github.com/255097

Jacek Becela said on 12/28 at 07:11 PM

Brian, thanks for mentioning nano. Didn’t know it was that fast ;)

aefxx said on 01/09 at 07:39 PM

Hi Brian.
Great work, I relly appreciate it. It’s exiting to see my plugin (jQote) mentioned here and it performed quite well, it seems.

There are two things I’d like to add, though:
- jQote actually catches up with the mustache engine if you would simply omit the template’s formatting, that is getting rid of insignifficant whitespaces.
With jQuery 1.4a2 (aka 1.3.3) jQote outperforms all the other engines.

- You’ve got a typo in your link list: it’s jQote - not jQuote.

Keep up the good work, Brian.
cheers
aefxx

Commenting is not available in this weblog entry.

We're the Developers

at Viget Labs. We write about web development trends, tips, best practices, industry events, and our projects — all with an emphasis on Ruby on Rails.

Recent Comments

Your post has made me think!

We people get used to that what we daily do. And normally we forget that we have to evolve.

Contact Us

Have any questions, comments, ideas, or secrets to share? Let us know.


How many days in a non-leap year?

Sorry, you need to have Javascript enabled to use this form. (Don't blame us, blame the spammers!) If you'd like to contact us, please visit our Contact page.