mauricemach/coffeekup — pull request #87 by omarkhan (2011-10-20 21:55:52+00:00)
Title: Optimize compiled templates

I have been experimenting with optimizing coffeekup templates using [UglifyJS](http://github.com/mishoo/UglifyJS) to analyze the template source and prerender the html. The idea is to turn this:

```javascript
function() {
//
// Lots of boilerplate code...
//
html(function() {
head(function() {
return title(this.title);
});
return body(function() {
h1(this.title);
return p('Super fast templates');
});
});}).call(data);return __ck.buffer.join('');
}
```

into this:

```javascript
function() {
//
// Much less boilerplate
//
((function() {
text("");
text("");
text(function() {
text("

");
text(function() {
return function() {
text("

");
text(this.title);
text("

");
}.call(data);
}.call(data));
text("

");
return function() {
text("

");
text(function() {
text("

");
text(this.title);
text("

");
return function() {
text("

");
text("Super fast templates");
text("

");
}.call(data);
}.call(data));
text("

");
}.call(data);
}.call(data));
text("");
})).call(data);return __ck.buffer.join('');
}
```

The advantages of this approach are shorter template functions (unless the template is very long) thanks to reduced boilerplate, and faster execution owing to much of the work being done at compile time. Here are my benchmark results, running a compiled template 5000 times on node:

CoffeeKup (precompiled): 261 ms
CoffeeKup (precompiled, optimized): 55 ms
Jade (precompiled): 536 ms
haml-js (precompiled): 90 ms
Eco: 109 ms

See here for browser rendering performance: http://jsperf.com/coffeekup-optimized

As far as I can tell, these optimizations give a 5x performance boost with v8 javascript, and a more modest 2x improvement in Firefox.

## Usage

```coffeescript
template = coffeekup.compile 'h1 @title', optimize: yes
template(title: 'Super fast template')
# '

Super fast template

'
```

## Caveats

As this compiler uses static analysis to optimize your templates, too much complex logic may cause it to fall over. But templates should be logic-free so that should be a problem, right?

I have aimed for API compatibility with regular coffeekup, but there are a few differences to be aware of:

- The `coffeescript` helper function does not add `"text/coffeescript"` to the `