From The Server To The ClientClient-Side Templating

Advertisement

Using templates in the browser is becoming more and more widespread. Moving application logic from the server to the client, and the increasing usage of MVC-like patterns (model–view–controller) inspired templates to embrace the browser. This used to be a server-side only affair, but templates are actually very powerful and expressive in client-side development as well.

Client-side templating article image1
Image Credit: Viktor Hertz2

Why Would You Use It?

In general, leveraging templates is a great way to separate markup and logic in views, and to maximize code reusability and maintainability. With a syntax close to the desired output (i.e. HTML), you have a clear and fast way to get things done. Although templates can be used to output any kind of text, in this article we provide examples using HTML, since that is what we want in client-side development.

In today’s dynamic applications, the client frequently needs to update the user interface (UI). This might be done by fetching an HTML fragment from the server that can be readily inserted into the document. Yet this requires the server to support delivering such fragments (as opposed to complete pages). Moreover, as a client-side developer who is responsible for the markup, you want to have full control over your templates. No need to know anything about Smarty, Velocity, ASP, some other obscure server-side syntax or even worse: dealing with spaghetti code such as HTML containing those infamous <? or <% tags all over the place.

So let’s take a fresh look at a viable alternative: client-side templating.

First Impressions

For starters, I’d like to give a definition of the term “template”. Here is a good definition3 from foldoc:

“A document that contains parameters, identified by some special syntax, that are replaced by actual arguments by the template processing system.”

Let’s observe an example, and see what a basic template might look like:

<h1>{{title}}</h1>
<ul>
    {{#names}}
        <li>{{name}}</li>
    {{/names}}
</ul>

This probably looks pretty familiar if you know HTML. It contains HTML tags with some placeholders. We will replace them with some actual data. For instance with this simple object:

var data = {
    "title": "Story",
    "names": [
        {"name": "Tarzan"},
        {"name": "Jane"}
    ]
}

Combining the template and data should result in the following HTML:

<h1>Story</h1>
<ul>
    <li>Tarzan</li>
    <li>Jane</ul>
</ul>

With the template and data separated, it becomes easy to maintain the HTML. For example, changing tags or adding classes will only need changes in the template. Additionally, adding an attribute to repeating elements such as the <li> element only needs to be done once.

Template Engine

The syntax of the template (i.e. the format of the placeholders such as {{title}}) depends on the template engine you want to use. This engine takes care of parsing the templates, and replacing the placeholders (variables, functions, loops, etc.) with the actual data it is provided.

Some template engines are logic-less. This doesn’t mean you can only have simple placeholders in a template, but the features are pretty limited to some intelligent tags (i.e. array iteration, conditional rendering, etc.). Other engines are more feature-rich and extensible. Without going into details here, a question to ask yourself is whether and how much logic you allow in your templates.

Although each template engine has its own API, usually you will find methods such as render() and compile(). The render process is the creation of the end result by putting the actual data in the template. In other words, the placeholders are replaced with the actual data. And if there is any templating logic, it is executed. To compile a template means to parse it, and translate it into a JavaScript function. Any templating logic is translated into plain JavaScript, and data can be fed to the function, which concatenates all the bits and pieces together in an optimized way.

A Mustache Example

The production of the example above can be performed by using a template engine, e.g. mustache.js. This uses the popular Mustache templating syntax. More about them, and alternatives, later. Let’s take a look at a little JavaScript to produce some results:

var template = '<h1>{{title}}</h1><ul>{{#names}}<li>{{name}}</li>{{/names}}</ul>';
var data = {"title": "Story", "names": [{"name": "Tarzan"}, {"name": "Jane"}]};

var result = Mustache.render(template, data);

Now we want to show this in the page. In plain JavaScript this could be done like this:

document.body.innerHTML = result;

That’s all! You can try the above in your browser by placing the Mustache script before your own code:

<script src="https://raw.github.com/janl/mustache.js/master/mustache.js"></script>

Or, you can try this example at jsFiddle4.

Organizing Templates

If you’re like me, you probably don’t like to have the HTML in one long string. This is hard to read, and hard to maintain. Ideally, we can put our templates in separate files so we still have all the benefits of syntax highlighting, and the ability to properly indent the lines of HTML for readability.

But this leads to another issue. If our project contains a lot of templates, we don’t want to load all of those files separately, since this issues a lot of (Ajax) requests. This would be bad for performance.

Scenario 1: Script Tags

An often seen solution is to put all the templates within <script> tags with an alternative type attribute, e.g. type="text/template" (which is ignored for rendering or parsing by the browser):

<script id="myTemplate" type="text/x-handlebars-template">
    <h1>{{title}}</h1>
    <ul>
        {{#names}}
            <li>{{name}}</li>
        {{/names}}
    </ul>
</script>

This way, you can put all of your templates in the HTML document and prevent all the extra Ajax requests to those templates.

The content of such a script tag can then be used later in your JavaScript as a template. The following code example, this time using the Handlebars templating engine and a bit of jQuery, uses the previous <script> tag:

var template = $('#myTemplate').html();
var compiledTemplate = Handlebars.compile(template);
var result = compiledTemplate(data);

You can try this example as well at jsFiddle5.

The result here is the same as in our Mustache example. Handlebars can use Mustache templates as well, so we use the same template here. There is one (important) difference though, which is that Handlebars is using an intermediate step to get the HTML result. It first compiles the template into a JavaScript function (we named it compiledTemplate here). This function is then executed using the data as its only argument, returning the final output.

Scenario 2: Precompiled Templates

While only one function to perform the template rendering may seem convenient, there are significant advantages to splitting up the compilation and rendering process. Most importantly, this allows for the compilation part to happen on the server-side. We can execute JavaScript on the server (e.g. using Node), and some of the templating engines support this precompilation of templates.

Putting it all together, we can organize and serve a single JavaScript file (say, compiled.js) that contains multiple, precompiled templates. This could roughly look like this:

var myTemplates = {
    templateA: function() { ….},
    templateB: function() { ….};
    templateC: function() { ….};
};

Then, in the application code we only need to populate the precompiled template with data:

var result = myTemplates.templateB(data);

This is generally a far better-performing approach than putting templates within <script> tags as discussed before, since the client can skip the compilation part. Depending on your application stack, this approach is not necessarily harder to accomplish, as we’ll see next.

Node.js example

Any template precompilation script should at least do the following:

  • read the template files,
  • compile the templates,
  • combine the resulting JavaScript functions in one or more files.

The next basic Node.js script does all that (using the Hogan.js templating engine):

var fs = require('fs'),
    hogan = require('hogan.js');

var templateDir = './templates/',
    template,
    templateKey,
    result = 'var myTemplates = {};';

fs.readdirSync(templateDir).forEach(function(templateFile) {

    template = fs.readFileSync(templateDir + templateFile, 'utf8');
    templateKey = templateFile.substr(0, templateFile.lastIndexOf('.'));

    result += 'myTemplates["'+templateKey+'"] = ';
    result += 'new Hogan.Template(' + hogan.compile(template, {asString: true}) + ');'

});

fs.writeFile('compiled.js', result, 'utf8');

This reads all files in the templates/ folder, compiles the templates and writes them to compiled.js.

Note that this is highly unoptimized code, and does not include any error handling. Still, it does the job, and shows that it doesn’t require a lot of code to precompile templates.

Scenario 3: AMD & RequireJS

The Asynchronous Module Definition (AMD) is gaining more and more traction. Decoupled modules are often a great way to organize an application. One of the most popular module loaders is RequireJS. In a module definition, dependencies can be specified, which will be resolved and made available to the actual module (factory).

In the context of templates, RequireJS has a “text” plugin that allows you to specify text-based dependencies. AMD dependencies are treated as JavaScript by default, but templates are just text (e.g. HTML), so we use the plugin for that. For example:

define(['handlebars', 'text!templates/myTemplate.html'], function(Handlebars, template) {

    var myModule = {

        render: function() {

            var data = {"title": "Story", "names": [{"name": "Tarzan"}, {"name": "Jane"}]};
            var compiledTemplate = Handlebars.compile(template);
            return compiledTemplate(data);

        }
    };

    return myModule;
});

This way, the advantage lies (only) in the ability to organize the templates in separate files. This is nice, but it needs an extra Ajax request to get the template, and it still needs to compile the template client-side. However, the extra request can be removed by using the r.js optimizer that comes with RequireJS. This resolves dependencies, and will “inline” the templates (or any dependency) into this module definition, vastly reducing the number of requests.

The absence of a precompilation step can be solved in a couple of ways. It may come to mind to have the optimizer also precompile the templates (e.g. we could write a plugin for r.js). But that would require a change in the module definition as well, since we would be using a template string before optimization, and a template function afterwards. Yet this would not be terribly hard to deal with, either by checking for this variable type, or by abstracting away this logic (in either the plugin or the application).

Watching Templates

In both scenarios #2 and #3, we can do even better by treating our templates as uncompiled source files. Just like CoffeeScript, or Less or SCSS files. We can have our template files watched for changes during development, and recompile them automatically when a file is changed, i.e. just like you would compile CoffeeScript into JavaScript. This way, we’re always dealing with precompiled templates in our code, and the optimizer effortlessly inlines the precompiled templates in the build process.

define(['templates/myTemplate.js'], function(compiledTemplate) {

    var myModule = {

        render: function() {

            var data = {"title": "Story", "names": [{"name": "Tarzan"}, {"name": "Jane"}]};
            return compiledTemplate(data);

        };
    };

    return myModule;
}

Performance Considerations

Rendering UI updates by using client-side templates is often the way to go. Still, the best performance for the initial full page load is achieved by serving that page as a whole. This allows the browser to render the HTML as is without requiring any JavaScript parsing or extra requests for data. This might be a challenge, especially for pages that are both dynamic and require the best initial loading times possible. Then, ideally, templates are being developed and reused on the client and the server to both support the best performance and still be maintainable.

Two questions to consider here are:

  • What part of my application is mostly dynamic, and what part requires the best possible initial loading times?
  • Do you want to move the processing to the client, or should the server do the heavy lifting?

The answer can only be given by actually measuring different approaches. Yet by using precompiled templates, the client usually doesn’t have a very hard time rendering them on the fly. And in case you want to reuse templates on the client and server, you will find a logic-less template syntax to be the most versatile.

Conclusion

We have seen many strengths of client-side templating, including:

  • Application servers and APIs are best at serving just the data (i.e. JSON); client-side templates fit in perfectly.
  • HTML and JavaScript naturally match the skills of client-side developers.
  • Using templates enforces a good practice of separating presentation and logic.
  • The templates can be fully precompiled and cached, this leaves only the actual data to be refreshed from server.
  • Moving the rendering phase from server to client may positively affect performance.

We have been looking at quite some aspects of (client-side) templating. Hopefully by now you have a better understanding of the concept, and why you would use it.

(cp)

Footnotes

  1. 1 http://www.smashingmagazine.com/wp-content/uploads/2012/12/client-side-template.jpg
  2. 2 http://www.flickr.com/photos/hertzen/4878410201
  3. 3 http://foldoc.org/template
  4. 4 http://jsfiddle.net/webpro/huuDd/
  5. 5 http://jsfiddle.net/webpro/9xwum/

↑ Back to topShare on Twitter

Advertising
  1. 1

    Those are fair statements, Rex. First of all, using client-side templates is mainly beneficial for applications (less so for static websites). Additionally, in the section “Performance Considerations” I mention that templates can also be rendered server-side (by reusing templates on server). This would solve the “JavaScript turned off” scenario, since the page is served as a whole. Making the templates available on the client as well would allow for partial updates of the UI at runtime (and this is why it is mainly beneficial for more dynamic websites/applications).

    1
    • 2

      Lars is exactly right. The portability of the “UI bits” between the server or the client is a huge win. I can prototype with these JavaScript templating solutions and later decide to execute the compiled JS on the server (node.js or even RhinoScript on Java) or instead execute them on the browser. I get to choose. With the traditional JSP, JSF, ASF, Python, PHP or what-have-you you don’t get template portability. Sometimes you want a more seamless app experience (like in mobile) and you render the template at runtime in the client. Other times you may want to render on the server side. But the same template can be run in either place.

      0
  2. 3

    Wouldnt this be a serious problem for the user if javascript is turned off? If content on the website is solely dependant on javascript for being displayed, that would pose some serious issues.

    I dont know… I am not really convinced by this method, but it sounds nice and all. Maybe it’s because i don’t see a viable application of this. In what scenarios is this beneficial?

    0
    • 4

      This technique is a really good for Web Application development.
      Now if you expect your users to use a webapp with JS disabled. I suggest you wait for HTML6-7 or something.

      0
  3. 5

    Very good introduction article.
    I am just surprised that you don’t mention bi-directional data-binding (i.e. to trigger automatic template refresh when the data model changes). This is indeed a very handy and natural feature that is frequently at the core of the latest client-side template engines (cf. angular or ember JS).
    For those interested, here are some more thoughts on this topic:
    http://ariatemplates.com/blog/2012/11/key-features-for-client-side-templates
    Thx,
    Bertrand.

    0
  4. 6

    I’m toying with the idea of a client side repository of templates, where you can embed as many templates in the HTML (in tags) and have others fetched through an XHR call; those will be then cached in the page for later reuse. Using something like the “use” pattern of YUI, you could even do batch request of templates.

    0
  5. 7

    Found a small typo in the example code under Scenario 2 for the properties in your object.

    temlateA: function() { ….},
    etc

    Assuming that should read:
    templateA: function() { ….},

    Interesting that I just heard about this on an older episode of Shop Talk Show yesterday. Good timing of this article for me as it expounded on what they discussed. Thanks!

    0
  6. 8

    I could really see this being great for the navigation section of a website. If you have to add just one page to a 50 page site updating the navigation links on every page would obviously be tedious even with a good editor like Sublime Text.

    @Rex Lars does mention how to turn it into a server side solution.

    0
  7. 9

    Lars,

    We’re using Twig & TwigJS with Symfony2. The Twig templates are pre-compiled into both PHP & JS so then we can render on whichever side we’d prefer, which it is nice.
    We load the JS templates asynchronously after the page loads, but what if the template hasn’t been loaded yet? (Example: if you’re too quick at clicking a button which trigger a (client-side rendered) modal, nothing will happen)
    Is it best practice to queue the templates to be loaded (ordered by probability of use first)? Therefore if the template hasn’t been retrieved yet, move it to the top of the queue. I’m not really into loading screens.
    This is especially a problem in older browsers where assets aren’t loaded in parallel.

    0
  8. 10

    I was into this whole templating ideas a while ago, it seemed like the most reasonable solution for Ajax and so on. But this guy showed me a more semantical, smart and to be honest, quite obvious way to do “templating”. http://blog.nodejitsu.com/micro-templates-are-dead

    0
  9. 11

    @Bertrand: I wanted the article to be as library/framework agnostic as possible. Besides, data-binding is a very relevant topic of course, but not necessarily a feature for templates (or template engines).

    @Matt Chestnut: Thanks for the catch; I see the editor has already fixed it.

    @Adam Lynch: That’s a very common use case. It’s probably a good idea to combine multiple templates in a single request. And since you are relying on JavaScript anyway (to open a modal), one solution might be to initially hide/disable the links that trigger the modal with JavaScript(!) as quickly as possible; then show/enable them as the template becomes available. And sometimes it might be acceptable to just be unresponsive for the first x ms. Too many factors are in play (UX, performance, etc.), I can’t cover them all here :-)

    0
    • 12

      Lars,

      Thanks for answering.

      “It’s probably a good idea to combine multiple templates in a single request.”
      We do combine assets (with Assetic) but if you’re really taking advantage of templating (template inheritance, inclusion, etc), it can still really mount up.

      Hmm, letting it be unresponsive is the easy way out though. If you theoretically had an infinite amount of template scripts to load, you’d wouldn’t wait for them to load to show call to action buttons, right? I’m not sure of all the pros and cons of a queue like I said but maybe it’s better because with the action will complete (albeit slower than if the script was loaded), as opposed to not responding at all and throwing a error in the console.

      “Too many factors are in play (UX, performance, etc.), I can’t cover them all here :-)”
      Yeah, I thought it was a bit too broad of a question. Surprised you answered.

      I was also wondering, why is so much effort being put into making templating engines only for client-side? Surely, it’s not best to have to keep two collections of templates in sync. To me at least, that seems to sustain most of the original problems, as if you were manually building HTML strings in JS and had separate templates/views for server-side.

      0
  10. 13

    “[…] even worse: dealing with spaghetti code such as HTML containing those infamous <? or <% tags all over the place."

    Good to know that double curly brackets mixed with javascript are considered way superior.

    I appreciate your effort, but what exactly is the point of shifting the templating engine to the client-side when you lose compatibility with users that have javascript deactivated, and more importantly search engines. By shifting it from the server side, you make substantial losses without any benefits – apart from the fact that someone might prefer a client-side language over a server-side language that is. This however would be putting personal preference over the flexibility of the website.

    By the way, MVC has nothing at all to do with “embracing the browser.”

    0
  11. 14

    Good introduction – always helps to remember to have template in the textarea and not elsewhere like div, allways helpls to stick to those basics and the ones you mention above.

    0
  12. 15

    @Tim Sweeney: Thanks for stopping by.

    > Good to know that double curly brackets mixed with javascript are considered way superior.

    That’s not what I intended to say. My point is that in those “templates” you see lots of (server-side) logic that shouldn’t be there, which sometimes quickly ends up in a maintenance nightmare. You also took it out of context, because I started the sentence with actual templating solutions, and took it from there to make a point: separation of markup and logic (as the section started with).

    > [..] javascript deactivated, and more importantly search engines [..]

    Please read my first comment above, it also applies to SEO: http://coding.smashingmagazine.com/2012/12/05/client-side-templating/#comment-622814

    > By the way, MVC has nothing at all to do with “embracing the browser.”

    What I write is that more application logic and more MVC in the client *inspired* templates to embrace the browser. I.e. templates are also happy to be (compiled and) rendered in the browser (which I definitely think is closely related to model data and views).

    0
    • 16

      @Lars

      Thanks for taking the time to reply and I am not here to have a heated debate of any kind. However, let me try to elobarate my points:

      1. If you suggest the main purpose of this client-side templating is not for static websites, bur rather for web-applications that don’t require SEO, I believe you should clarify it in the article. I’m not exactly sure what sort of web-application would need client-side templating, but there might be cases where this is a valid option.

      2. MVC is a design pattern in software architecture. I’m sorry to say that nothing in your article even closely resembles MVC.

      3. I appreciate any debate on technology and new ideas and I understand you are want to make a case for client-side templating. However, I believe it is important to keep things in perspective wherefore I’d like to follow up the bullet-points of your conclusion.

      .- “Application servers and APIs are best at serving just the data (i.e. JSON); client-side templates fit in perfectly.”
      The perfect fit would be server-side caching, possibly combined with technologies on the client-side to reduce overhead. Client-side templating is only a option if SEO is entirely irrelevant to your project and/or you have no way to exploit the power of the server-side.

      -“HTML and JavaScript naturally match the skills of client-side developers.”
      While I agree that convenience of the designer/dev can be one of many criteria, it shouldn’t compromise more important factors such as flexibility and accessibility of a website.

      -“Using templates enforces a good practice of separating presentation and logic.”
      Absolutely true. This is good practice, however, and applies in general rather than for client-side templating only.

      -“The templates can be fully precompiled and cached, this leaves only the actual data to be refreshed from server.”
      Precompiling is possible with server-side templating (not client-side) and is definitely a big advantage. I can only assume that you are talking about optimised JS code, because I wouldn’t know how actual precompilation of a template would work whilst it’s supposed to be parsed on the client.

      -“Moving the rendering phase from server to client may positively affect performance.”
      If we assume that the server is extremely slow and has no caching whilst we ignore parsing time on the client-side, I can see how it might increase performance. Under normal circumstances, I wouldn’t expect any advantages at all. In fact, most common cases I’d expect a marginal performance loss which would be neglibable however, and therefore not worth mentioning. I would definitely be interested in taking a look at your benchmarks and the testing conditions which yield a significant performance gain.

      4. On a closing note, I truly appreciate your effort, but I think it’s important to list both benefits and limitations in order for readers to make a qualified decision on whether or not they want to invest their resources into a certain technology.

      0
      • 17

        Tim,

        I’d like to chime in here because I think some of what you mentioned is a little off. I agree however that the article should be clearer about use-cases where you’d want this approach.

        There are largely three approach to writing a web app:

        1. Do everything on the server. JS is used only for small enhancements to client-side functionality. This approach is the same as a standard web site. All requests are synchronous, but we use caching to alleviate some performance problems.

        2. PJAX-style. A slight variation on the above. All requests are asynchronous but instead of sending data back to be rendered on the client, the data is rendered on the server and is simply inserted at the correct position on the client. Performance will be a lot better here (no complete page reloads), but you still need caching on server.

        3. Client-side MVC with server-side (RESTful?) API. All requests are asynchronous, the server handles only data, everything is rendered client-side. Data can be cached server-side, templates can be cached client-side.

        The first approach isn’t great for web apps, the reason being that there’s only so much you can cache. If you have lots of dynamic data (it is a web app after all) then it is not realistic to heavily cache everything for every user. Lots of page reloads, so the app feels clunky and not very speedy to use. However, should work without JS.

        The second approach is better, no page reloads so the site is a lot more responsive, but you still have the caching problem, you can’t possibly cache everything for every user! However, your stack is very simple, with little client side code, and can likely be progressively enhanced so it’ll work without JS. This is the approach used by basecamp BTW.

        The final approach is the best for highly responsive web apps. You have a lot of client-side code which some may dislike, but your server is likely very simple. You will have greater success with caching because the server only caches data (likely a lot smaller weight than the HTML the data is rendered into), and you can cache requests client-side for extra speed. Everything is rendered client-side, probably through templates, because it will quickly become a mess to generate elements individually via jQuery or something. Will not work without JS.

        Hopefully from this you can see that it is perfectly valid to have client-side templating in web apps, providing it fits your needs (For a web *site* this is, of course, the completely wrong approach). For instance, most of the google apps themselves are client-heavy (GMail, Google Maps etc), and performance and responsiveness is a feature for them, so it’s fair to assume that they use client-side templating of some kind, combined with a server-side API.

        With regards to SEO, most web *apps* sit behind a log in/pay wall and so are impervious to search engine bots.

        0
        • 18

          Hi Nick,

          I appreciate the detailed reply.

          As for your third case, in addition a client-side MVC, you would very likely also find a server-side MVC, rather than a thin server. One of many reasons would be input validation that you can’t do on the client or with just a model on the server. Having said that, you can have a thin client as you stated in your first twoexamples, but having a thin server provides entirely new challenges that might not be so easy to overcome. I’m aware that it’s possible to have model states, but input validation is only one of several issus that would need to be addressed here.

          There are potential gains from only caching actual data on the server-side, but these gains and their significance always need to be compared to the trade-offs you make elsewhere. Does a more effective use of cache justify a fat server AND a fat client? In some applications it might, indeed, in a lot of others it’s questionable from an economic and maintenance point of view.

          0
          • 19

            Hey Tim,

            Server-side MVC was supposed to be encompassed by my first point. I wasn’t discussing specific approaches but high-level architectures and the level of server/client involvement in each approach. A thin server would still do data validation, but it’s done in the service (rather than in the server-side web app as you’d find in a fat server), the client is then responsible for simply echoing any validation errors.

            Personally i think that this approach will become more and more prominent and widely adopted in future. But in the end, as with most things, which approach is best is entirely dependent on your requirements and the state of your current art.

            0
          • 20

            Tim, no offense; but your understanding of modern web application development seems to be pretty outmoded. With the advent of Backbone.js, Ember, Angular, et all; a LOT more smarts are now sitting on the client. You’d be wise to brush up on what’s happening in this wild and wacky world of web.

            0
  13. 21

    As described here, this is not at all useful for apps (as opposed to “mere” web pages). Once the template has been populated in the client, it’s no longer a template; subsequent updates would require identifying the target DOM elements. We already have a means of identifying DOM elements quite apart from funky template-oriented syntax. Attributes, remember? The best one could hope to achieve with a scheme like this is to move a copy of the template (or a means of creating a copy) into the template-populating code. That’s just mixing aspects of the page in a new and even more scary way. (Can one safely say whether an element ought to be identified uniquely or as a class using the template-element name? Let’s examine the CSS as well as the HTML.)

    What makes sense for Node.js doesn’t necessarily apply in any way to client-side JavaScript. The language is not the environment. While such a system may be perfectly fine for assembling documents or document fragments prior to service, it makes zero sense client-side unless and until browsers support a static DOM by default (there is limited access to the source document at run-time, and that doesn’t include simultaneous access to both the source document AND the changes made to it). It utterly fails to address the no-script issue unless the user agent decides to broadcast having scripting disabled—and what about unreliable connections? If I fail to load an Ajax request, do I just see a bunch of {{name}} stuff? (Incidentally, I have much the same complaint about the implementation of web fonts. When I’m mobile, a lot of the time I see a text-free page since the font-family fallback is not based on whether I have the font, but whether I theoretically have the means to acquire the font. A failed @font-face request means I see nothing that uses that font, and the license-tracked font bureau requests—all brands—tend to fail quite often.)

    0
  14. 22

    Unneccessary gimmicks like these produce slow, irritating and browser-crashing web pages. Instead of just being simple, beautiful and informative, you generate a simple looking page with massive overhead, which only is beautiful until the ad blocker, security addon, some JS error or mobile device limitations disable essential functionality of your JS-built page and the user angrily decides to visit the competitor’s site.

    Plus, it regularly leads template designers into creating irrationally behaving JS-powered features (like those horrible tablet-templates over at Blogger, which make reading a longer text or browsing through articles almost impossible)

    The best *theoretical* template system is one which generates static pages on the server, that can be fetched and viewed with even a limited browser, which can fall back on non-JS features (example: a lightbox script that opens the picture in a new window if defunct).

    0
  15. 23

    Jimmy Breck-McKye

    December 6, 2012 6:02 am

    Given that these pages won’t work without javascript, won’t they be completely invisible to search engines? Googlebot only executes JS in specific conditions, and I don’t believe the Bing or Yahoo! spiders run JS at all.

    0
  16. 24

    Some people are missing the point here!
    There isn’t about the S.E.O or even static websites.
    this is the future of application development.
    Great article.
    Lars, congrats!

    0
  17. 25

    Some people seem to miss the point of pre-compilation of templates on the server. HTML templates can be compiled into a JavaScript function. This (reusable) function is served to the client, and can be fed data. The output is rendered HTML. This function makes a template parser/compiler needless on the client. Consuming internal or external API’s that serve JSON in a rich app make a great use case for using client-side templates.

    What I did not mention in the article is SEO (I think I missed it since I’m mostly working on fat client applications; less static websites). The performance considerations actually apply to SEO as well: (partial) server-side rendering is obviously good for both initial loading time and SEO. On many pages, when SEO is important, that page is not a complex application (i.e. client-side templates may not add much here). But when it is, a hybrid model (i.e. reuse some or all templates on client and server) is worth the investigation.

    If the only thing you care about is performance, serve instant HTML at all times, and cache rigorously.

    In short, this article is intended to be an introduction and to make you think about it (more logic on client / MVC patterns, performance considerations). Every situation has its own constraints, and requires its own approach and investigation. There’s simply no one-size-fits-all.

    Here’s some related reading by others (covering some use cases and performance):

    http://engineering.linkedin.com/frontend/leaving-jsps-dust-moving-linkedin-dustjs-client-side-templates
    http://engineering.twitter.com/2012/05/improving-performance-on-twittercom.html
    http://ryanflorence.com/2012/client-v-server-templating/

    0
    • 26

      In regards to SEO, I believe server or client-side templating is less of an issue than people think. Google now crawls with a smartphone user-agent so it will (in theory) see your site the same way as smartphone sees it.

      http://googlewebmastercentral.blogspot.ca/2011/12/introducing-smartphone-googlebot-mobile.html

      Googlebot actually id’s itself as an iPhone with UA: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html).

      Treat it as an iPhone and Google will do the rest.

      0
  18. 27

    Interesting post, I was kind of in the subject right now. I released a DOM-based template engine, fast and fully featured. It is not a template engine that is string based, which have numerous advantages as stated here:
    http://blog.stevensanderson.com/2012/08/01/rich-javascript-applications-the-seven-frameworks-throne-of-js-2012/
    And here:
    http://soundstep.github.com/soma-template/#credits

    Here is the library if you are curious:
    http://soundstep.github.com/soma-template

    I’d be curious to get your feedback.

    Hope that will help some developers.

    Romu

    0
  19. 28

    In the web-world nowadays you have a very powerful templating language built into web-browsers – CSS – it (combined with perhaps a smidgeon of JavaScript) can take very simple markup and convert it into whatever the “designer” wants it to look like (think of the CSS Zen garden)…. Templating then in this sense is perhaps less useful (and can in a lot of cases be detrimental) in separating display from logic (after all that is what CSS is for!)… Instead developing components that take data structures + simple configuration to produce simple HTML constructs is a far easier and more optimal solution especially in sites which are rendering large quantities of data. Templates work best at either the macro (layout) or micro (inline) levels – but not often in the middle ground of tables, lists etc – but most of these templating engines are not designed to work at these two extremes – but in the middle ground – the area where they are least suited for use.

    0
  20. 29

    I think SpacePen is one of the best client side view frameworks since it is technically a jQuery sub class.

    https://github.com/nathansobo/space-pen

    It allows you to author your views to be smart, but don’t go overboard and make your views be both the V and the C in MVC. I highly recommend an article I wrote titles “View Controller Patterns With Spine.JS & SpacePen” and feel free to ignore the Spine.JS part. The overall point is MVC in JavaScript and how a smart view layer that encapsulates logic in that view for said view is a good thing.

    http://metaskills.net/2012/05/22/view-controller-patterns-with-spine-js-and-spacepen/

    0
  21. 30

    1+ for handlebars, it’s a lot more flexible than mustache. It’s great when i adopt a trend before I see it on smashing magazine! I despise seeing html come back in server side calls, it’s just extra fat, and a lot less flexible than sending JSON back. The only thing I hate worse than this is seeing multi-line html inside of a JS file how it makes me cringe with the end of each line commented out with a . It’s amazing how much quicker it is to edit the templates when you want to change presentation markup, but I think the bigger advantage is how much easier it is to read and understand the Javascript file when all of the markup is out of it.

    0
  22. 31

    after reading the article and the comments I am still where I was an hour ago. I just don’t see the point in a javascript template engine.

    Let’s say for example, I am building a page which has a repeatable region, a blog post index for example. I have a code block for my post which has a title, a date, an author, a content excerpt, links to the post and some other meta data. I want to show the last five and paginate.

    I need to write a sql query to get that content. How am I going to do that with javascript? I’m not. So now I’ve got server side code to run my queries, I may as well stick everything in one place. otherwise I am creating a back end system and an API for that system just so I can completely separate the ‘front-end’ but I always have to make calls to the database.

    Or is that the whole point?
    I just don’t get it.

    0
  23. 32

    Seems that a LOT of people are confused here and seem to be missing the overall point. SEO is absolutely NOT a factor for the type of application that this approach is optimized for (since this application will likely be a “single page” Web Application that sits behind some sort of authentication zone)

    The power of this approach really comes into play when you work with frameworks like Backbone.js (http://documentcloud.github.com/backbone)

    Your client side templates will more than likely represent different “views” onto a “model” (with the view listening to events being emitted by the model, such as property changes and updating itself accordingly) These views rendered via the client side templates are -highly- dynamic, with highly granular measures of invalidation (as opposed to a static page, which would need a full server roundtrip to re-render after the data it represents is invalidated)

    I’m not sure why the author of this well written article is being shouted down, could be a result of the readership of smashingmag being designers who don’t fully understand this evolving approach to web app development?

    0
  24. 33

    I’ve written about Client-Side Templating with dot.js a few months ago, if you’re interested

    http://blog.rogerdudler.com/post/29910317444/client-side-templating-with-dot-js

    0
  25. 34

    I’m quite shocked at the amount of people that don’t understand that this is the future of web-app development (not the templating per-se, but all the rest).
    Maybe Smashing Magazine average user knowledge has been lowering lately.
    Nowadays I see job offers for frontend developers popup constantly, it’s an exciting world to be involved in, mobile devices, html5, the death of flash, the webappification of everything, it’s far more exciting than any server side language, and you never run the risk of getting too niche or out of market like on a ss language.
    The truth is, people thought they could be front end developers forever by just knowing html4, coming to the comments sections and preach people about not using b or i tags, talking for days about doctypes, pretend to be important and future-proof while endlessly talking about html5 tags semantics and other bullcrap. Well they can go back to 2005 because it’s 2013 now and in the meantime the real world has already embraced all these technologies.
    A couple years ago I realized for myself that js templating was needed while I was concatenating javascript object attributes and html strings and felt clumsy. If you never felt this way it means you don’t even know what AJAX is and should probably start to catch up. Or you can spend another day ranting on how I should use the aside tag.

    0
  26. 35

    First, this is a bit of a shameless plug for my nifty open-source (MIT) client-side template engine project…

    http://www.kruntch.com
    http://www.kruntch.com/blog.htm
    https://github.com/davidvaccaro/kruntch.js

    While client-side JavaScript templating may not be a perfect fit for all applications, for many it works quite nicely.

    After using a few other approaches for typical client-side MVC and MVVM, I decided that in some cases I would like to have a really simple, single-purpose client-side templating system that would function as a non-invasive (no behind the scenes DOM manipulation) tool… something that I could easily use to complement other standard libraries (i.e. jQuery, jQuery Mobile, ExtJS, etc.) without having to buy-in to another big framework with lots of specific features and best practices.

    So, after doing a little Googleing, I decided that I would write my own engine and turn it into an open-source project (at GitHub) and viola! I give you Kruntch.js.

    Check out the Kruntch.js home (http://www.kruntch.com) and blog (http://www.kruntch.com/blog.htm) for lot’s of examples on how you can use Kruntch.js.

    Generally though it is VERY simple approach and very similar to the details outlined in this article BUT there are also some pretty nifty features like collection looping, indexing, filtering and targeting and a minimal but fairly powerful template-view-model (TVM) concept.

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top