How to Enable Gzip Compression for NGINX PageSpeed Module Resources: A Technical Deep Dive


2 views

When running Google PageSpeed Insights, many developers encounter a puzzling scenario where standard content compresses perfectly, but PageSpeed-optimized resources stubbornly remain uncompressed. This happens because PageSpeed modifies resources on-the-fly, creating new cache files that bypass your standard gzip configuration.

Your base NGINX gzip configuration needs these essential directives:

gzip on;
gzip_types text/plain text/css application/javascript application/x-javascript 
           text/xml application/xml application/xml+rss text/javascript 
           application/json image/svg+xml;
gzip_vary on;
gzip_proxied any;
gzip_min_length 256;
gzip_comp_level 5;
gzip_buffers 16 8k;

The key is to modify your PageSpeed configuration block to handle these dynamic resources:

pagespeed EnableFilters compress_js,compress_css;
pagespeed EnableFilters rewrite_javascript,rewrite_css;
pagespeed EnableFilters collapse_whitespace;

location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
  add_header "" "";
  gzip on;
  gzip_types *;
  gzip_proxied any;
}

location ~ "^/ngx_pagespeed_static/" {
  gzip on;
  gzip_types *;
  gzip_proxied any;
}

Check compression with these terminal commands:

curl -I -H "Accept-Encoding: gzip" http://yoursite.com/modified-resource.js
curl -s -H "Accept-Encoding: gzip" http://yoursite.com/resource | file -

For optimal performance with compressed PageSpeed resources:

pagespeed FileCachePath /var/ngx_pagespeed_cache;
pagespeed FileCacheSizeKb 2048000;
pagespeed FileCacheCleanIntervalMs 3600000;
pagespeed FileCacheInodeLimit 500000;
  • Ensure your PageSpeed version supports gzip (1.6.29.5+ recommended)
  • Verify your kernel supports zlib compression
  • Check for conflicting compression modules like Brotli
  • Confirm your content-length exceeds gzip_min_length

While NGINX's gzip module works perfectly for regular content, PageSpeed-optimized resources often bypass compression due to their unique handling pipeline. The core issue lies in the processing order: PageSpeed modifies resources after gzip would normally compress them.

Add these directives to your NGINX config before any PageSpeed declarations:

# Enable gzip for PageSpeed resources
pagespeed EnableFilters rewrite_javascript,rewrite_css;
pagespeed EnableFilters combine_javascript,combine_css;
pagespeed EnableFilters collapse_whitespace;
pagespeed EnableFilters defer_javascript;
pagespeed EnableFilters inline_javascript;
pagespeed EnableFilters inline_css;

# Critical compression settings
pagespeed HttpCacheCompressionLevel 9;
pagespeed RewriteLevel OptimizeForBandwidth;

Update your server configuration with these location blocks:

server {
    # ... existing config ...

    location ~* \.(js|css)$ {
        gzip_static on;
        gzip_types text/javascript application/javascript text/css;
        gzip_proxied any;
        gzip_comp_level 9;
        gzip_min_length 256;
    }

    location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
        gzip on;
        gzip_types *;
        add_header "" "";
    }
}

Test compression using curl:

curl -I -H "Accept-Encoding: gzip" http://yoursite.com/pagespeed_resource.js

Look for these headers in response:

Content-Encoding: gzip
Vary: Accept-Encoding

For maximum performance, pre-compress common assets:

find /var/www/html -type f -name "*.js" -exec gzip -k9 {} \;
find /var/www/html -type f -name "*.css" -exec gzip -k9 {} \;
  • Verify PageSpeed version supports compression (1.9.32.1+)
  • Check error logs: tail -f /var/log/nginx/error.log
  • Disable other optimization modules that might conflict
  • Clear PageSpeed cache after config changes