Detailed guide

Text Compression Implementation Guide

View contents

Complete Guide to Text Compression Implementation for Web Performance

Introduction

Text compression can reduce transfer sizes by 60-90%, making it one of the highest-impact performance optimizations available. This guide provides comprehensive implementation strategies for different server environments and hosting platforms.

New to compression? Start with our beginner-friendly guide: 📖 Read: Text Compression Explained

Strategy 1: Server-Level Compression

Nginx Configuration

# /etc/nginx/nginx.conf or /etc/nginx/conf.d/compression.conf

# Enable gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 256;

# Compress these MIME types
gzip_types
  application/atom+xml
  application/geo+json
  application/javascript
  application/json
  application/ld+json
  application/manifest+json
  application/rdf+xml
  application/rss+xml
  application/x-javascript
  application/xhtml+xml
  application/xml
  font/eot
  font/otf
  font/ttf
  image/svg+xml
  text/css
  text/javascript
  text/plain
  text/xml;

# Enable Brotli (requires ngx_brotli module)
brotli on;
brotli_comp_level 6;
brotli_types
  application/atom+xml
  application/javascript
  application/json
  application/rss+xml
  application/xhtml+xml
  application/xml
  font/eot
  font/otf
  font/ttf
  image/svg+xml
  text/css
  text/javascript
  text/plain
  text/xml;

Apache Configuration

# .htaccess or httpd.conf

# Enable mod_deflate for gzip
<IfModule mod_deflate.c>
  # Force compression for mangled Accept-Encoding headers
  <IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
      SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~telerik|{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
      RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
    </IfModule>
  </IfModule>

  # Compress HTML, CSS, JavaScript, Text, XML, fonts
  <IfModule mod_filter.c>
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/ld+json
    AddOutputFilterByType DEFLATE application/manifest+json
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE font/eot
    AddOutputFilterByType DEFLATE font/otf
    AddOutputFilterByType DEFLATE font/ttf
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
  </IfModule>

  # Don't compress already-compressed files
  SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|avif|woff2?)$ no-gzip
</IfModule>

# Enable mod_brotli (Apache 2.4.26+)
<IfModule mod_brotli.c>
  AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css
  AddOutputFilterByType BROTLI_COMPRESS application/javascript application/json
  AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
  BrotliCompressionQuality 6
</IfModule>

Node.js/Express Configuration

// Using compression middleware
const compression = require('compression');
const express = require('express');

const app = express();

// Enable compression for all responses
app.use(compression({
  // Compression level (0-9, higher = better compression, more CPU)
  level: 6,
  // Only compress responses larger than 1KB
  threshold: 1024,
  // Filter which responses to compress
  filter: (req, res) => {
    if (req.headers['x-no-compression']) {
      return false;
    }
    return compression.filter(req, res);
  }
}));

// For Brotli support, use shrink-ray-current
const shrinkRay = require('shrink-ray-current');

app.use(shrinkRay({
  brotli: { quality: 6 },
  zlib: { level: 6 }
}));

Strategy 2: Build-Time Pre-Compression

Pre-compressing static assets during build offers the best compression ratios since you can use maximum compression levels without affecting response time.

Webpack Configuration

// webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');
const zlib = require('zlib');

module.exports = {
  plugins: [
    // Generate .gz files
    new CompressionPlugin({
      filename: '[path][base].gz',
      algorithm: 'gzip',
      test: /\.(js|css|html|svg|json)$/,
      threshold: 1024,
      minRatio: 0.8,
    }),
    // Generate .br files (Brotli)
    new CompressionPlugin({
      filename: '[path][base].br',
      algorithm: 'brotliCompress',
      test: /\.(js|css|html|svg|json)$/,
      compressionOptions: {
        params: {
          [zlib.constants.BROTLI_PARAM_QUALITY]: 11, // Max quality
        },
      },
      threshold: 1024,
      minRatio: 0.8,
    }),
  ],
};

Vite Configuration

// vite.config.js
import { defineConfig } from 'vite';
import viteCompression from 'vite-plugin-compression';

export default defineConfig({
  plugins: [
    // Gzip compression
    viteCompression({
      algorithm: 'gzip',
      ext: '.gz',
      threshold: 1024,
    }),
    // Brotli compression
    viteCompression({
      algorithm: 'brotliCompress',
      ext: '.br',
      threshold: 1024,
    }),
  ],
});

Nginx Serving Pre-Compressed Files

# Serve pre-compressed files if available
location ~ ^/assets/ {
  # Try .br first, then .gz, then original
  gzip_static on;
  brotli_static on;

  # Add proper headers
  add_header Vary Accept-Encoding;

  # Cache static assets
  expires 1y;
  add_header Cache-Control "public, immutable";
}

Strategy 3: CDN-Level Compression

Most CDNs handle compression automatically, but configuration options vary.

Cloudflare Configuration

Cloudflare Dashboard → Speed → Optimization

✅ Auto Minify: HTML, CSS, JavaScript
✅ Brotli: Enabled (automatic for HTTPS)

Note: Cloudflare automatically:
- Serves Brotli when supported
- Falls back to gzip
- Caches compressed versions

AWS CloudFront

{
  "CacheBehavior": {
    "Compress": true,
    "ViewerProtocolPolicy": "redirect-to-https",
    "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6"
  }
}

Vercel/Netlify

Both automatically compress with Brotli/gzip—no configuration needed.

Strategy 4: Compression Level Optimization

Understanding Compression Levels

Compression Level Trade-offs:
┌─────────────────────────────────────────────────────────────┐
│ Level │ Gzip Size │ Brotli Size │ CPU Time │ Best For       │
│───────│───────────│─────────────│──────────│────────────────│
│ 1     │ 100%      │ 100%        │ Very Low │ Real-time APIs │
│ 4     │ 92%       │ 90%         │ Low      │ Dynamic content│
│ 6     │ 88%       │ 85%         │ Medium   │ Default balance│
│ 9     │ 86%       │ 80%         │ High     │ Pre-compression│
│ 11*   │ N/A       │ 75%         │ Very High│ Static assets  │
└─────────────────────────────────────────────────────────────┘
* Brotli only (levels 10-11)
Dynamic Content (APIs, server-rendered HTML):
├── Gzip: Level 4-6
├── Brotli: Level 4-5
└── Rationale: Balance compression vs response time

Static Assets (JS, CSS, pre-built):
├── Gzip: Level 9
├── Brotli: Level 11
└── Rationale: Compress once, serve many times

Real-time Data (WebSocket, streaming):
├── Gzip: Level 1-2
├── Brotli: Not recommended
└── Rationale: Minimize latency

Strategy 5: Minification + Compression

Minification and compression work together for maximum savings.

Combined Pipeline

Original File Optimization Pipeline:
┌─────────────────────────────────────────────────────────────┐
│ styles.css                                                  │
│ ├── Original: 150 KB                                        │
│ ├── After Minification: 95 KB (37% smaller)                │
│ ├── After Gzip: 18 KB (88% smaller than original)          │
│ └── After Brotli: 14 KB (91% smaller than original)        │
│                                                             │
│ app.js                                                      │
│ ├── Original: 500 KB                                        │
│ ├── After Minification: 180 KB (64% smaller)               │
│ ├── After Gzip: 52 KB (90% smaller than original)          │
│ └── After Brotli: 42 KB (92% smaller than original)        │
└─────────────────────────────────────────────────────────────┘

Why Both Matter

// Minification removes:
// - Whitespace, comments
// - Long variable names → short names
// - Dead code

// Compression exploits:
// - Repeated patterns (class names, keywords)
// - Common byte sequences

// Together: Maximum reduction
// Minified code compresses better because
// shorter variable names repeat more consistently

Strategy 6: Testing and Verification

Using curl for Testing

# Test gzip support
curl -H "Accept-Encoding: gzip" -I https://example.com/styles.css
# Look for: Content-Encoding: gzip

# Test Brotli support
curl -H "Accept-Encoding: br" -I https://example.com/styles.css
# Look for: Content-Encoding: br

# Test with both
curl -H "Accept-Encoding: gzip, br" -I https://example.com/styles.css
# Should return br (preferred)

# Get actual compressed size
curl -H "Accept-Encoding: gzip" -so /dev/null -w '%{size_download}' https://example.com/styles.css

Automated Testing Script

#!/bin/bash
# compression-check.sh

URL=$1
echo "Testing compression for: $URL"
echo "---"

# No compression
SIZE_NONE=$(curl -so /dev/null -w '%{size_download}' "$URL")
echo "Uncompressed: ${SIZE_NONE} bytes"

# Gzip
SIZE_GZIP=$(curl -H "Accept-Encoding: gzip" -so /dev/null -w '%{size_download}' "$URL")
ENCODING_GZIP=$(curl -H "Accept-Encoding: gzip" -sI "$URL" | grep -i content-encoding)
echo "Gzip: ${SIZE_GZIP} bytes (${ENCODING_GZIP})"

# Brotli
SIZE_BR=$(curl -H "Accept-Encoding: br" -so /dev/null -w '%{size_download}' "$URL")
ENCODING_BR=$(curl -H "Accept-Encoding: br" -sI "$URL" | grep -i content-encoding)
echo "Brotli: ${SIZE_BR} bytes (${ENCODING_BR})"

# Calculate savings
if [ "$SIZE_NONE" -gt 0 ]; then
  SAVINGS_GZIP=$((100 - (SIZE_GZIP * 100 / SIZE_NONE)))
  SAVINGS_BR=$((100 - (SIZE_BR * 100 / SIZE_NONE)))
  echo "---"
  echo "Gzip savings: ${SAVINGS_GZIP}%"
  echo "Brotli savings: ${SAVINGS_BR}%"
fi

Measuring Impact

Before/After Comparison

BEFORE Compression Optimization:
├── Total Transfer Size: 1.8 MB
├── TTFB: 850ms
├── FCP: 2.4s
├── Lighthouse Performance: 62
└── Page Load (3G): 12.5s

AFTER Compression Optimization:
├── Total Transfer Size: 380 KB (↓79%)
├── TTFB: 420ms (↓51%)
├── FCP: 1.1s (↓54%)
├── Lighthouse Performance: 89 (↑27 points)
└── Page Load (3G): 4.2s (↓66%)

Lighthouse Audits

Check for these audit results:

  • “Enable text compression” - Should show 0 resources
  • “Properly size images” - Separate from text compression
  • “Minify CSS/JavaScript” - Complements compression

Optimization Checklist

Before deploying, verify:

  • [ ] Gzip enabled for all text-based MIME types
  • [ ] Brotli enabled for HTTPS traffic
  • [ ] Pre-compression for static assets (level 9-11)
  • [ ] Dynamic compression at level 4-6
  • [ ] Images/videos excluded from compression
  • [ ] WOFF2 fonts excluded (already compressed)
  • [ ] Vary: Accept-Encoding header present
  • [ ] CDN compression enabled
  • [ ] Minification applied before compression
  • [ ] Compression verified with curl or DevTools

Continue optimizing your resource delivery:

📚 Back to Performance SEO Hub - Explore all performance topics


References

  1. MDN Web Docs - Content-Encoding
  2. web.dev - Minify and Compress Network Payloads
  3. Chrome Developers - Enable Text Compression
  4. Nginx Documentation - ngx_http_gzip_module

Try It Yourself

Ready to optimize your site’s compression?

🔧 Download UXR SEO Analyzer (Free, 100% local analysis)


Disclaimer: The analyzers in this extension are reference guides based on official documentation from MDN, web.dev, and Chrome Developers. They do not represent absolute truths about how search engines evaluate your content—only search engines know their internal algorithms. Use these recommendations as a starting point to improve your site.

Last updated: December 15, 2025

Related articles

Related version

Introduction

Text Compression Explained

Text compression is one of the most effective ways to reduce file sizes and improve page load times

Category hub

Hub

Performance Seo Hub

Performance is a critical ranking factor and directly impacts user experience

In the same category

Detailed guide

Ttfb Optimization Guide

Time to First Byte (TTFB) is the foundation of web performance—every millisecond of TTFB delays your entire page load

Detailed guide

Caching Headers Optimization Guide

HTTP caching is one of the most powerful performance optimizations available

Detailed guide

Render Blocking Resources Optimization Guide

Render-blocking resources are one of the most impactful performance issues you can fix