Currently working on optimizing some templates on a large website. I found some interesting things.
I'm using precompiled templates and jinja2 compat mode
Some observations / questions
1. Variables in loops not cached
{% for entry in entries %}
{{ some.other.object.value }}
{% endfor %}
is much slower than
{% set value = some.other.object.value }}
{% for entry in entries %}
{{ value }}
{% endfor %}
I've only just begun looking into the Nunjucks code but I suspect there is not much optimization going on in the compile step. Any object.key.value access seems to be a bit slow.
2. How are {% includes %} optimized?
Our codebase is heavily partialized, so we use a lot of {% includes... %} throughout the codebase. We had a few macros like:
{% macro blah() %}
{% include 'test.html' %}
{% endmacro %}
and I noticed that, if this macro was used in a loop for instance, that replacing the include with the contents of the file made the macro 25% faster or so. I would imagine {% includes %} on a compiled template are just a function call to the compiled template but one function call doesn't seem to justify a 25% slowdown
3. Try/Catch in the compiled code.
In compiler.js (
https://github.com/mozilla/nunjucks/blob/master/src/compiler.js) emitFuncBegin and emitFuncEnd emit a try/catch block. Doesn't this force the whole template to go into "non-optimized" mode in v8? I'll be testing the speed with and without the try/catch block in the next few days when I have some time. But has there been any work to investigate some of the try/catch strategies out there on the web? Or is this non-issue?
Any other well-known gotchas when writing templates? The template rendering on a few of our pages is greater than 1 second. After some simple optimizations (#1, #2) I've reduced the time by around 40% but I'm interested in other optimization tips.
Thanks
--
Shaun