0

I am mixing jade with handlebars so that I don't have to write HTML and can have the nice syntax for data-related stuff.

For example, this might be the template for header, header.handlebars.jade

html
  {{#with user}}
  {{if user.username}}
  header Welcome back, {{username}}
  {{/if}}
  {{/with}}

I am wondering if I should precompile this template with jade and then handlebars when I'm using it server-side on node.js? If I don't, I am basically compiling this template 2 times (first jade, then handlebars) on each request.

I am not entirely sure if this plays any role, but it seems that both jade.compile and Handlebars.compile are synchronous functions, which means they are blocking other requests as long as the compilation takes place.

ragulka
  • 4,312
  • 7
  • 48
  • 73
  • Jade is considered slow by some, however it is hard to answer this sort of question for _every_ case. I suggest you construct a benchmark for _your_ specific case and check the results. (For example, number of concurrent connections per server load). Generally it is always worth compiling your templates if you are able. – Benjamin Gruenbaum Mar 13 '13 at 15:15

1 Answers1

0

Yes, precompiling your templates can be a good idea. The reason is that using a template generally consists of two steps:

  1. Parsing
  2. Generating a string from the data and the parsed template

Parsing is an expensive operation. It basically consists of a identifying tokens (special words) and building a tree structure. For example:

{{#with author}}
  <h2>By {{firstName}} {{lastName}}</h2>
{{/with}}

This block can be thought as tree with a parent with statement and several children "<h2>By ", firstname, lastName and "</h2>".

When you precompile a template what you're doing is generating code that's the result of parsing and generating that tree structure, so each time you use that code you don't need to parse and generate the tree. You're saving many CPU cycles.

The logic is the same as whether you should read some files synchronously at the start up of your server or to read them every time. If you read the template files at the beginning you do less IO operations, but you're using more memory to store the content of those templates. The same goes for parsing.

What many of us do is identify which assets will be used a lot (templates are usually in this category), cache them in memory and leave the rest to be read on-demand. This means that you can't just change a template and update your site. You need to version your site and in order to make an update you have to kill the Node process and restart it. Whether that's a good idea for your site will depend on how you organize your deployments.

As far as combining Jade and Handlebars, it doesn't look like a good idea because it's a more expensive operation to have render two different templates and because you can only precompile one of them. You can't precompile both of them because one template depends on the result of the other. In your case the "source code" for the Jade template depends on the result of applying the Handlebars template.

juandopazo
  • 6,283
  • 2
  • 26
  • 29
  • Thanks for your thorough answer. Actually, I understand the rationale and general idea behind precompiling templates (I do it for the client-side). I was just thinking if I should precompile for server-side as well (it doesn't look like express+jade is precompiled by default). As for mixing jade and handlebars - my Jade template output does not actually depend on Handlebars. I am always parsing Jade first, then Handlebars. I'm using Jade only because I don't want to write plain HTML. However, your idea about loading templates once on app startup and caching them is interesting. – ragulka Mar 13 '13 at 15:46
  • Yeah I should've explained the difference between precompiling and compiling. Precompiling in Handlebars is actually the same as compiling but returning JavaScript source code as a string instead of executable code. That is, `eval(precompile(tpl)) <=> compile(tpl)`. I'll update my answer later. – juandopazo Mar 13 '13 at 17:04