The race by browser developers to develop even faster JavaScript engines has made client side templating a realistic alternative to server side templating. Any decision to use client side templating is very much a tradeoff; the following should be considered:
| Client side templating | Server side templating | |
|---|---|---|
| Server/client performance | Faster server response; slower on client | Slower server response; faster on client |
| Bandwidth | Serves a smaller JSON response; but will also need to request the javascript template engine | Serves larger HTML response; no extra javascript libraries |
| Javascript Clients | Must have javascript enabled | Javascript not required |
| Search Engine friendly | No; will need to sniff out search engine bots and serve them HTML | Yes |
| Caching | Cache templates & JSON | Cache entire response of some pages |
| Seperation of Concerns | Cleaner split; enabling HATEOS allowing client and server to evolve independently | Server returns entire HTML response; client and server coupling |
| Multiple Devices | Serve JSON to alternative devices | Requires client sniffing in order to serve appropriate response |
Our boilerplate will support both client and server side templating; it will also support template pre-compilation.
Content Negotiation
In order to support both client and server side templating from within the same application we need to be able to serve JSON and HTML. express supports content negotiation; see below example; which is an HTTP concept whereby a resource can be represented in multiple formats; a HTTP requests accept header will determine which representation is returned.
The below route for our homepage demonstrates how content negotiation works in express; we will serve JSON for our client side templating and HTML for server side templating.
API
Below is the api for our home page referred to in the above snippet; its loosely based on a REST architecture constraint known as HATEOS - Hypermedia as the Engine of Application State; which is effectively a decoupling of client/server allowing both to evolve independently. The concept is actually very simple when a client requests a resource the server will return a response which contains a series of hypermedia based interactions; links essentially to the various actions the user can now perform based on the current state; but I degress.
Server Side Templating
Consolidate.js allows us to abstract away any server side templating engine we decide to use with express providing us with a consistent api when rendering views; configuring consolidate.js is very simple; simply add the following piece of configuration to your main node/express application; our app will now support dust.js:
Client Side Templating
Templating on the client side works by configuring express to serve a JSON response. Ideally a CDN/cache server will serve the HTML templates; our boilerplate application is configured to allow express to serve these; but this is really just to demonstrate the concept. The HTML template will make an AJAX call to get any data the page requires; the template engine will then load the data into the view.
Further performance gains can be accomplished by pre compiling the template and saving it to a JavaScript file, thus avoiding compilation on the client. You can also then request the runtime version of dust.js which is considerably smaller than the full version required when compiling on the client.
Client side templating with pre compiled templates
In order to pre-compile dust.js templates I have put together a simple node.js console application dust-down which will compile all dust.js templates in a given folder. The snippet below also includes in a script tag the pre-compiled templates.
Client side templating with client side template compilation
This is basically the same as the snippet above but does not include any pre-compiled templates; these are compiled on the client. This also requires the full version of dust.js.
Test drive
In order to test drive the various templating options, edit the views located here:
node-plates\node.jquery.mobile\public\views
You will see below three templating options; comment in/out the templating option you are testing
Now start the node-plates application:
node server.js
Make sure you comment in/out the correct scripts in each view:
To see server side templating open a browser and visit the below; express is serving this via the routing for HTML we have setup :
http://127.0.0.1:3000/about
To see client side templating open a browser and visit the below; express is serving this via the built in static file server; i.e. any files in the public folder are served this way. The HTML template will make a AJAX/JSON call to get the data for this page:
http://127.0.0.1:3000/views/about.html
About
This post is part of a series of posts tagged under node-plates a boilerplate mobile/web application written in node.js, express, socket.io, mongooose, jquery.mobile & html 5.
Github
You can grab this from github ->
https://github.com/AndrewKeig/node-plates
References
akdubya.github.com/dustjs/
github.com/visionmedia/consolidate.js
github.com/AndrewKeig/dust-down
A really interesting read.
ReplyDeleteHowever, I fail to understand how you can compile the template based on the page HTML?
var compiled = dust.compile($('#index').html(), 'index');
It will returns you pure HTML, with no dust.js tags, and thus, when you render it with the client-side, it will keep render the same HTML regardless of whatever context you pass in.
hey thanks;
ReplyDeletevar compiled = dust.compile($('#index').html(), 'index');
The above line will perform a client side compilation on each request of the page; the option you are referring to is not the pre-compiled option; so yes; it will render the same html.
The pre-compiled option actually compiles these html pages down to a javascript function; you simply include it on the page as a normal javascript include and load it.
Cheers
Hi fellas!
ReplyDeleteEverything is clear except when , where and how is the dust.js file is invoked?
In your code ex: node-plates.js
Also in a normal scenario, where will this js(node-plates.js) file be??
in the CDN or in the server side ??