How To Pre-Compress Your Website With Gzip On Debian 10 And Apache2

Whenever you visit a website you will almost certainly recieve compressed .html, .css, .js and .xml files. This because they are very compressible, over 90%, which saves bandwidth and speeds up load times.

However, they’re compressed by the webserver every time they are served. This is a waste of CPU cycles and places extra load on both the webserver and the client. The anser is to compress all of these files once on the server and serve the pre-compressed files.

Here’s how.

The first thing you need to do is to enable mod_deflate, mod_headers and mod_rewrite

a2enmod deflate headers configtest

Next you need to create the Apache2 configuration which will:

  1. Serve pre-compressed .html, .css, .js and .xml files if they exist.
  2. Avoid re-compressing the pre-compressed files.

Open a new configuration file at /etc/apache2/conf-available/:

nano /etc/apache2/conf-available/pre-compress.conf

And copy and past the following code:

<IfModule mod_headers.c>
    # Serve gzip pre-compressed CSS and JS, HTML and XML files
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.(css|js|html|xml)"         "$1\.$2\.gz" [QSA]

    # Serve correct content types, and prevent second compression.
    RewriteRule "\.js\.gz$"   "-" [T=text/javascript,E=no-gzip:1]
    RewriteRule "\.html\.gz$" "-" [T=text/html,E=no-gzip:1]
    RewriteRule "\.xml\.gz$"  "-" [T=text/xml,E=no-gzip:1]
    RewriteRule "\.css\.gz$"  "-" [T=text/css,E=no-gzip:1]

    <FilesMatch "(\.js\.gz|\.css\.gz|\.xml\.gz|\.html\.gz)$">
      # Set the encoding type.
      Header append Content-Encoding gzip

      # Force proxies to cache pre-compressed and 
      # standard files separatly
      Header append Vary Accept-Encoding


Thanks to the Apache Documentation for help with the code.

You should always verify your Apache2 configuration before restarting the webserver because bad config will stop Apache2 from starting:

# apachectl configtest
Syntax OK

Finally, you need to comperss your .html, .css, .js and .xml. Something like the following will work:

find <PATH THE SITE CONTENT> -type f | grep -e ".html$" -e ".css$" -e ".xml$" -e ".js$" | xargs gzip -9 -k