# Brotli or gzip compression enabled on text assets

- **Pattern:** `ab-002017` (`performance-core.script-style-efficiency.compression`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002017
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002017)

## Why it matters

Uncompressed text assets transfer 2–5x more bytes than their compressed equivalents (ISO-25010 resource-utilisation). A 245 KB JavaScript bundle served without compression transfers 245 KB; with Brotli compression it transfers approximately 55 KB — a 78% reduction. Every kilobyte saved reduces time-to-interactive on constrained connections, cuts CDN egress costs, and directly improves LCP for users on slower networks. Brotli consistently outperforms gzip by 15–25%, making it the preferred algorithm for static text assets.

## Severity rationale

Low because major hosting platforms enable compression by default, so this finding usually indicates a custom server misconfiguration rather than a novel issue — but the byte impact can be substantial.

## Remediation

Verify compression is active by checking response headers:

```bash
curl -sI -H "Accept-Encoding: br, gzip" https://yoursite.com/js/app.js | grep -i content-encoding
# Expected: content-encoding: br  (or gzip)
```

For Node.js servers without a CDN or reverse proxy in front, add the `compression` middleware:
```ts
// server.ts
import compression from 'compression'
import express from 'express'

const app = express()
app.use(compression())  // enables gzip by default
```

For Brotli (better compression ratio), use `shrink-ray-current` instead:
```ts
import shrinkRay from 'shrink-ray-current'
app.use(shrinkRay())  // serves br for capable clients, gzip as fallback
```

Vercel, Netlify, and Cloudflare enable Brotli by default — no configuration needed on those platforms.

## Detection

- **ID:** `compression`
- **Severity:** `low`
- **What to look for:** Check server response headers for `Content-Encoding: gzip` or `Content-Encoding: br`. Test with `curl -H "Accept-Encoding: gzip, deflate, br"`. Verify that text assets (HTML, CSS, JS, JSON) are compressed. Check CDN or server configuration for compression settings.
- **Pass criteria:** Text assets (HTML, CSS, JS) are compressed with gzip or Brotli. Compression ratio is 40-60% (e.g., 100KB JS becomes 40KB gzipped). Response headers show `Content-Encoding: gzip` or `br`.
- **Fail criteria:** Text assets served uncompressed, or compression is disabled. Large files (over 100KB) transfer without compression. Response headers missing `Content-Encoding`.
- **Skip (N/A) when:** All assets are already small (under 50KB) and network bandwidth is abundant.
- **Detail on fail:** Specify uncompressed assets. Example: `"app.js 245KB served without compression; with gzip would be 60KB. Content-Encoding header missing"` or `"All CSS files uncompressed; styles.css 85KB could be 20KB gzipped"`.
- **Remediation:** Enable compression on your hosting platform:

  **Vercel:** Enabled by default.
  **Netlify:** Enabled by default.
  **AWS:** Enable compression in CloudFront behavior settings.

  Or configure on custom servers (Node.js):
  ```ts
  import compression from 'compression'
  app.use(compression())
  ```

## External references

- iso-25010 performance-efficiency.resource-utilization

Taxons: performance, operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-002017
