Text Compression: Gzip and Brotli

Easy

Compression is one of the easiest performance wins - massive size reduction with minimal setup.

Quick Decision Guide

Enable compression on your server:

Nginx: gzip on; or brotli on; in config Apache: Enable mod_deflate in .htaccess Node.js: Use compression middleware CDN: Cloudflare/Netlify/Vercel enable automatically

Result: 70-90% smaller files, dramatically faster load times.

Important: Only compress text files (HTML/CSS/JS/JSON), not images/videos.

Gzip vs Brotli

FeatureGzipBrotli
Compression~70%~80%
SpeedFastSlower
SupportAll browsersModern only
Use caseUniversalBest quality
Level 1: Fastest, less compression
Level 6: Balanced (recommended)
Level 9: Best compression, slowest

Best practice: Use level 4-6 for dynamic content, level 9 for static assets (pre-compressed).

Server Configuration

Nginx

# Gzip
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types 
  text/plain 
  text/css 
  text/xml 
  application/json 
  application/javascript 
  application/xml+rss 
  application/atom+xml 
  image/svg+xml 
  text/javascript;

# Brotli (if installed)
brotli on;
brotli_comp_level 6;
brotli_types 
  text/plain 
  text/css 
  application/json 
  application/javascript;

Apache (.htaccess)

# Enable mod_deflate
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
  AddOutputFilterByType DEFLATE application/javascript application/json
</IfModule>

Node.js/Express

const compression = require('compression');
const express = require('express');
const app = express();

// Enable compression
app.use(compression({
  threshold: 1024, // Only compress if > 1KB
  level: 6 // Compression level (1-9)
}));

app.get('/', (req, res) => {
  res.send('Response will be compressed');
});

Next.js

// next.config.js
module.exports = {
  compress: true, // Enabled by default in production
};

Pre-Compression

Static Assets

Pre-compress static files at build time for maximum compression.

// Build script
const fs = require('fs');
const zlib = require('zlib');
const brotli = require('brotli');

// Compress all JS/CSS files
const files = ['app.js', 'styles.css'];

files.forEach(file => {
  const content = fs.readFileSync(file);
  
  // Gzip
  fs.writeFileSync(
    `${file}.gz`,
    zlib.gzipSync(content, { level: 9 })
  );
  
  // Brotli
  fs.writeFileSync(
    `${file}.br`,
    brotli.compress(content, { quality: 11 })
  );
});

Serve Pre-Compressed Files

# Nginx: Serve .br or .gz if available
location ~* .(js|css|html|svg)$ {
  gzip_static on;
  brotli_static on;
}

Benefit: Better compression (level 11) without CPU cost on each request.

What to Compress

✅ Always Compress

HTML files
CSS files
JavaScript files
JSON responses
XML/SVG files
Text files

❌ Never Compress

Images (JPEG, PNG, WebP - already compressed)
Videos (MP4, WebM - already compressed)
Fonts (WOFF2 - already compressed)
ZIP/RAR files
PDFs (already compressed)

Size Threshold

// Only compress files > 1KB
compression({
  threshold: 1024
})

Small files may become larger after compression overhead.

Verification & Testing

Check if Compression is Enabled

Chrome DevTools:

1. Open Network tab

2. Look for "Content-Encoding: gzip" or "br" in Response Headers

3. Compare "Size" vs "Transferred" columns

Command Line:

# Check compression
curl -H "Accept-Encoding: gzip" -I https://example.com

# Should see:
# Content-Encoding: gzip
# Content-Length: 50000 (original)
# Actual transfer: 15000 bytes

Online Tools

Google PageSpeed Insights
WebPageTest
GTmetrix

Performance Impact

Before compression:
- app.js: 1.2MB
- styles.css: 180KB
- index.html: 45KB
Total: 1.425MB

After Brotli:
- app.js: 240KB (80% reduction)
- styles.css: 25KB (86% reduction)
- index.html: 8KB (82% reduction)
Total: 273KB (81% overall reduction)

Result: 5.2x faster download!