Django Templates versus Whitespace

Whilst performance tuning a large Django web site recently, I noticed how much pointless whitespace was in our HTML.

"Sure," I hear you say "but you've got gzip enabled. It will take care of it!"

Before we just assume, I decided to take some measurements. I'm big on measurements. You should never try to improve anything you can't measure - otherwise, you're just wasting your time!

Baseline

So, I started looking at the front page of our site. A quick wget shows me it's 180k, and just shy of 4000 lines.

As a test, I stripped all trailing whitespace. There goes 25k.

25k? That's a LOT of spaces!

Now, what about blank lines? Woop, there goes another 1.8k. Wait a minute, this is a 4000 line file!

Cause

Why is it all there?

It's quite obvious, once you think about it. Take this typical snippet of template:

<ul>
    {% for item in store_menu %}
    <li><a href="{{ item.url }}" {% if item == store_menu.current %}class="active"{% endif %}>{{ item.title }}</a></li>
    {% endfor %}
</ul>

Looks ok, right? No blank lines.

Except... tags don't render. So there's two blank lines there. In fact, there's 1+N, because everything after the {% for %} line is repeated. On top of that, the whitespace up to the {% endfor %} is also included.

Cleanup

So, how can we clean this up, whilst maintaining readable templates?

In fact, I feel the solution makes the templates more readable, at least as far as HTML goes.

<ul>{% for item in store_menu %}
    <li><a href="{{ item.url }}" {% if item == store_menu.current %}class="active"{% endif %}>{{ item.title }}</a></li>{% endfor %}
</ul>

So, I've moved the start of the for loop onto the line of the containing tag -- the ul in this case -- and the endfor onto the last line of the loop content.

This style makes it look like we've annotated the markup, rather than written templating.

comments powered by Disqus