12 Feb 2012

Mochiweb, Erlang and Gzip

I run Nitrogen on Mochiweb for two projects,  and I'm very satisfied with this setup sofar.
The only downside is that Mochiweb does not gzip content by default. The (otherwise very reasonable) reason given by its maker (Bob Ippolito) is here.

So I tested how bad the damage was. First with YSlow, a part of the great FireBug tool.
No pages were gzipped indeed, and the best candidates for improvements seemed to be all the javascripts that Nitrogen need on the client:

  <script src='/nitrogen/jquery.js' type='text/javascript' charset='utf-8'></script>
  <script src='/nitrogen/jquery-ui.js' type='text/javascript' charset='utf-8'></script>
  <script src='/nitrogen/livevalidation.js' type='text/javascript' charset='utf-8'></script>
  <script src='/nitrogen/nitrogen.js' type='text/javascript' charset='utf-8'></script>
  <script src='/nitrogen/bert.js' type='text/javascript' charset='utf-8'></script>


Altogether these are 5 download (with 5 times HTTP GET overhead) and about 380K data.
My first action was to minify them and put all in one file. There are lost of tools on the web that do this for you, but do mind that when put in one file they stay in the order specified above. If not, you'll get Javascript error referring to non-existing objects.

I tested it again in YSlow, and I went from 5 files totaling about 380K to one file of about 290K.
Next stop: Pingdom.  The one Javascript file took the longest to load ...

Using wf:header() and and serving a manually gzipped file turn out to be a good solution.
I made a Erlang/Nitrogen module called jscript.erl with this content:

%% -*- mode: nitrogen -*-
-module (jscripts).
-compile(export_all).
-include_lib("nitrogen/include/wf.hrl").

main() ->
    wf:header("Content-Encoding", "gzip"),
     #template { file="./site/templates/miniall.min.js" }.


It adds the gzip enconding to the header and then spits out the minified, gzipped javascript file of only 78K. Works like charm. This is not the best solution, because a browser that does not support gzip (do they still exist?) can't decode it. So it's better to first check if the browser supports gzip (check the header with wf:headers()) and serve the minified javascript file if gzip is not supported.


No comments:

Post a Comment