linkedin / dustjs

Asynchronous Javascript templating for the browser and server
http://dustjs.com
MIT License
2.91k stars 479 forks source link

Extremely slow render #496

Closed shakyShane closed 10 years ago

shakyShane commented 10 years ago

I'm trying to use Dust as the templating language for a new project, but I've run into some huge performance problems & I'm wondering if i'm using the library incorrectly.

Running the source code of this file: https://gist.github.com/shakyShane/52a7db0cbcf5bdb5aade through handlebars takes < 100ms.

Handlebars.compile(contents)({name: "shane"});

But if I put that same file through dust, it takes approx 1200ms...

dust.compileFn(contents, "123", false);
dust.render("123", {name:"shane"}, function (err, out) {
       cb(err);
});

Is Handlebars really 12x faster? Surely there's somthing I've missed here..

Thanks for any help.

sethkinast commented 10 years ago

Your timing looks right to me-- however, it's the compiling step that takes much longer for Dust templates. Rendering time is negligible.

skinast$ time ./bin/handlebars syntax.md.txt > /dev/null

real    0m0.123s
user    0m0.104s
sys 0m0.019s

skinast$ time ./dustc syntax.md.txt > /dev/null

real    0m1.069s
user    0m1.051s
sys 0m0.023s

The nature of Dust means that there's a little more to its compilation logic, since one template might be composed of many blocks. That said, compilation isn't something that should be happening often-- if you're running Dust as part of a webserver, it will cache your compiled templates, and if you're running Dust as part of a build process, it's unlikely to be the bottleneck step. In general, your strategy should be to serve up compiled templates, and Dust is very fast at rendering a compiled template.

shakyShane commented 10 years ago

@sethkinast - thanks for verifying that.

Yeah, I understand your point completely & I found that once Dust had actually generated the JS, the actual rendering was almost identical time-wise with handlebars...

... but, I'm creating a tool that needs to re-process files when they change, and for this use-case dust is just going to be too slow.

sethkinast commented 10 years ago

The other thing that might be worth considering is that Dust is much better at small templates, and composing those templates into larger pages.

The compile speed grows non-linearly as your template size increases. If you're regularly compiling these really big templates, then yeah-- Dust is unfortunately just not oriented towards your needs. But if you're only changing sections, you might consider recompiling only that section.

Additionally, if you have large amounts of text in a template, that's really data-- perhaps it would be helpful to move the data into the context JSON, and out of the template? Then Dust doesn't have to worry about it.

sethkinast commented 10 years ago

Okay, don't count us out quite yet! Check out #497 -- I've done a little investigation and I think we can provide you with the performance you need.

shakyShane commented 10 years ago

OMG that would be a dream come true!

My project was inspired by how cool DustJS is & I've been on a downer thinking I was going to have to use Handlebars.

shakyShane commented 10 years ago

Also worth noting that I'm not looking for a speed match, just something a lot closer than 12x :)

shakyShane commented 10 years ago

I've now found another issue with how I'm trying to use this.

If you attempt to render the file mentioned above, after disabling white-space suppression, you end up with "RangeError: Maximum call stack size exceeded"

var dust = require("dustjs-helpers");
var fs   = require("fs");
var md   = fs.readFileSync("./docs/index.md", "utf-8");

dust.optimizers.format = function (ctx, node) {
    return node;
};

dust.loadSource(dust.compile(md, "test"));

dust.render("test", {}, function (err, out) {

    // RangeError: Maximum call stack size exceeded
});
sethkinast commented 10 years ago

Resolved by #497.

shakyShane commented 10 years ago

tumblr_m0osrrhqmk1qzcv7no4_250