There’s an endless debate regarding server side VS client side templating on the web, so i’ll just say it right away to avoid getting caught in the crossfire: I don’t that one is better than the other, i do think that this is a classic case of right tools for the right job (and under the right circumstances). What i do want to share is a bit of a compromise, where you can leverage some of Jade’s power to increase your productivity and save some processing time in the client, without rendering the templates in runtime on the server.
Compiling Jade in development phase
The idea is simple: You can use jade to pre-compile views, those views can be –
- Templates that are not requiring run-time logical decisions to render
- Small view pieces that you normally would be hard-coded into your HTML
I’m talking about a win-win situation which will boost-up your productivity and even might save some unnecessary client template rendering.
Boost up your productivity
Many developers (me among them) like the eye-pleasing jade syntax, fortunately it’s not only shiny and pretty, but also provides some nice perks for your development flow.
- First of all, it saves keystrokes
- Second – it’s less error prone than HTML markup, where you may discover an unclosed div only after it’s corrupting your entire UI
- Also, it’s more readable (although some may disagree)
And last but most definitely not least, you can “templatize” pieces of HTML that you previously couldn’t. For example, lets say you’re using some pretty Kendo-Angular drop down. The directive can accept some bindings, in our case: k-rebind and k-options. So in every place you’re using this drop down, you will write:
<select kendo-drop-down-list data-k-rebind="vm.kRebind" data-k-options="vm.kOptions"></select>
In such case, if one day you’ll have to change/modify the dropdown widget, you’ll have to change it in every single place.
Or… you can use jade’s mixins:
include ./widgets.jade div A page with a dropdown +getDropdown
mixin getDropdown select#dropdown(kendo-drop-down-list, data-k-options="vm.kOptions", data-k-rebind="vm.kRebind")
And then compile it with:
jade content.jade --pretty
And the output will be:
<div>A page with a dropdown</div> <select id="dropdown" kendo-drop-down-list="kendo-drop-down-list" data-k-options="vm.kOptions" data-k-rebind="vm.kRebind"></select>
The outcome is that you have extracted the dropdown to its own template (something you’ll rarely do) without “paying” anything rendering-speed/memory wise.
In conclusion, easier to read + less mistakes + less keystrokes + more templates = higher productivity.
Boost client rendering speed
How many times did you use client templating just to avoid writing the same piece of HTML more than once? I’m not talking about templates that shown/hidden based on logical conditions or anything that requires any kind of logic. I’m talking about cases where you just wanted to avoid code duplication, so you used your client templating. God knows I’m a sinner. But I’m only human, and no reasonable human want to do the same work twice, surely not four times when the product guys will change their minds, and definitely not six times when they change their minds again. Yet, in my humble opinion, it’s insufficient reason to use client templating.
Consider the following case: You have multiple pages with the same header and footer, you use ng-include and not directives since you can’t see the point in modularizing these two views, you just want to avoid code repetition.
So you’ll have something like this:
<div>This is header</div>
<div>This is footer</div>
<div ng-include="'sub-header.html'"></div> <div> Content </div> <div ng-include="'sub-footer.html'"></div>
In this case, in order to fully render the view, your app will have to make 3 HTTP requests (sub-header, sub-footer, content) and use the template engine to render sub-header and sub-footer each time the user requests the view. A bit costly just to avoid code duplication.
Now consider this: Using jade to create 3 different views and then compile them into a single view while still in development, so you’ll have one complete view that won’t require client templating, nor an additional HTTP requests to work, but still will be separated into different files (I’ll discuss file size caveat later in the post). It will look something like this:
include ./sub-header.jade div This is my content include ./sub-footer.jade
div This is the header
div This is sub footer
Now, when we’ll compile content.jade –
jade content.jade --pretty
And the result will be:
<div>This is header</div> <div>This is my content</div> <div>This is footer</div>
Same result as we would’ve got if we used regular ng-include, but without unnecessary HTTP requests and client processing.
But the file size getting larger!
Definitely valid argument, obviously if we pre-compile every logic-less include, our files will get larger, so you need to ask whether you can or cannot afford those extra KBs.
Some questions you need to ask might be:
- What would be the higher number – amount of users using the application, or the amount of features and use time per each user? For example, if your application is some heavily featured GUI for IT professionals, the amount of the users will be relatively low, while the ‘visit time’ for each user will be long. In such case, it will make a lot of sense to pre-compile the templates so your server will help out the client.
- In which environment will the app run? Open to public or on local network? In local environments you can allow yourself to be less concerned about download speed, also making pre-compile a valid option.
- Is your current load-time is acceptable? If yes, then you might consider to gzip your requests (improving the request by around 50-90%), while adding some more KBs to your files, so the trade-off might be worth it.
I can go on and on about more considerations, but i believe that my point is clear enough. You shouldn’t blindly pre-compile your templates, you should benchmark the change and take many factors into consideration. But still, in my opinion, pre-compiling is a valid and helpful method to boost your client speed.