Some time ago I’ve show how to precompress js and css file with gzip to be available for Nginx’s mod_gzip. In default configuration Apache don’t have such module but similar functionality could be achieved with few custom rewirtes.

Basically we will start with these rewrites to serve gzipped CSS/JS files if they exist and the client accepts gzip compression:


RewriteEngine on
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.(js|css)$ $1\.$2\.gz [QSA]

Then we need to setup proper content types for such compressed files - I know how to do this in two ways:

  • pure rewrites with mod_header - witch should serve correct content type and prevent mod_deflate to gzip files that are already gzipped
    
    RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=manualgzip:1]
    RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=manualgzip:1]
    
    <ifmodule mod_headers.c>
    # setup this header only if rewrites above were used
    Header set Content-Encoding "gzip" env=manualgzip
    </ifmodule>
    
  • by using Files clause (we could add this globally in httpd.conf)
    
    <files *.css.gz>
    ForceType text/css
    Header set Content-Encoding "gzip"
    </files>
    <files *.js.gz>
    #ForceType text/javascript
    # lately this one is more popular
    ForceType application/javascript
    Header set Content-Encoding "gzip"
    </files>
    

Both ways work fine. First one sets no-gzip variable to bypass second time compression. Second one rely on such option in my mod_deflate’s config:

SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar|gz)$ no-gzip dont-vary

which won’t compress any gz file, and this is why I have to setup Content-Encoding to gzip manually.

In both cases you will end with javacript and CSS files served from earlier prepared precomressed versions, with proper content type without engaging mod_deflate regardless you use js/css or js.gz/css.gz extension. But I strongly suggest to use extensions without gz - you will be able to disable this mechanism without any change in website code.

If you don’t know how to prepare files just look here.

P.S.
I found another similar but BAD example - it’s using AddEncoding clause to add gzip content type to ALL gzip files - this will cause problems with other compressed files with gz extension ex. tar.gz. Don’t do this. My rules above are more selective.

Sources

http://stackoverflow.com/questions/7947906/add-expiry-headers-using-apache-for-paths-which-dont-exist-in-the-filesystemexternal link
http://stackoverflow.com/questions/9076752/how-to-force-apache-to-use-manually-pre-compressed-gz-file-of-css-and-js-filesexternal link