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-filesystem
http://stackoverflow.com/questions/9076752/how-to-force-apache-to-use-manually-pre-compressed-gz-file-of-css-and-js-files