Hack: Gzipping static content for Catalyst

ChrisDolan on 2007-03-03T08:06:55

All the major browsers support gzipped content, signalled by the HTTP request header "Accept-Encoding: gzip". Several toolkits support auto-gzipping dynamic content in this case (Catalyst::Plugin::Compress::Gzip, Apache::Compress and my own CGI::Compress::Gzip )

But what about static content (specifically .js and .css files)? Compression of static content doesn't matter as much because it will be cached after the first hit, but that first hit is also a first impression. Gzip can dramatically reduce the download size of the first hit, especially for sites with modern dynamic content (like scriptaculous and its ilk).

In my current Catalyst project, I added a step to gzip all of my .js and .css files as part of the build process, then I did somthing like this in my header template:

[% SET gz = !c.config.devsite && c.req.header('Accept-Encoding').search('gzip') ? '.gz' : '' %]
 
 


I deliberately turn it off on the dev site because I change those files without rebuilding the whole app.

On a related note, can someone recommend a JS squisher that has a nicer API than JavaScript::Minifier?


JavaScript squisher

malte on 2007-03-03T19:33:13

I'm sorry I can only unrecommend JavaScript::Squish. It produces non-working JS for very simple input.

These regexes worked for me:

        $output =~ s(^\s*//.*$)()gm; # c++ style comments on line without code
    $output =~ s(^\s+)()gm;      # leading white space
    my $end = "\s*[\r\n]+";
    $output =~ s(;$end)(;)g;     # no newline after ;
    $output =~ s({$end)({)g;     # no newline after {
    $output =~ s(\s+$)()mg;      # trailing space
    $output =~ s(\n+)(\n)g;      # multiple new lines
    $output =~ s(//[^"'\n]*$)()gm;  # c++ style comments that cant be in quotes
Use with super care. There will be numerous edge cases

Re:JavaScript squisher

ChrisDolan on 2007-03-03T20:57:38

Interesting, that's more detailed than my own conservative attempt:

$in =~ s{^/\*.*?\*/}{}gxms;
$in =~ s{^//.*?$}{}gxms;
$in =~ s{^[ ]+}{}gxms;
$in =~ s{\n+}{\n}gxms;
I deliberately only strip from beginning or ends of line to reduce risk of stripping from inside quotes. The above already chops enough that I can feel comfortable indenting and commenting my Javascript code thoroughly.