Can I Compress (with Dictionaries)?

This page is updated every minute, using the previous version to receive a tiny version of the next, compressed at the edge by Cloudflare.

Deploy:--
Next:
Count:0
Saved:--
Latest Deploy Transfer--
Uncompressed
--
Gzip
--
Actual
--
Waiting for deploy...
Deploy Loglive
Waiting for first deploy...
Cumulative
--
Gzip
--
Actual
How it works
  1. Dictionary registration: The first JS bundle response includes a Use-As-Dictionary header with a URL match pattern and a dictionary-id. Cloudflare's edge injects this header and stores the response body as a dictionary keyed by its SHA-256 hash. The browser caches the decoded body and remembers the dictionary ID for future requests matching the pattern.
  2. New deploy arrives: A Worker cron creates a new bundle every minute with unique parameters at a unique URL. The browser sees the URL matches the stored dictionary's pattern and sends Available-Dictionary (the SHA-256 hash) and Dictionary-ID (the ID from the original Use-As-Dictionary header) in the request.
  3. Edge compression: Cloudflare's edge receives the dictionary hash and ID, looks up the stored dictionary bytes, fetches the new bundle from R2 uncompressed, and delta-compresses it against the dictionary using Zstandard. The response is served with Content-Encoding: dcz.
  4. Tiny transfer: ~94 KB of code compresses to a few hundred bytes because 98%+ is identical between deploys. Only the unique parameters change.

Note: Each deploy bundle is ~94 KB of mock JavaScript code (simulated framework, libraries, and utilities) to approximate the size of a typical production SPA bundle. None of the mock code is executed — only a small configuration block at the end drives the visualization (color palette, tile seed, changelog). This mirrors real-world deploys where most of the bundle often is unchanged code.

Note: Some fetch-time variation may occur because serving DCZ on cache misses currently involves a dictionary lookup on the edge, which can add latency compared to gzip. On cache hits, the DCZ response is served directly and the transfer size advantage is fully realized.

Browser request with dictionary hash Cloudflare CDN fetch uncompressed bundle R2 R2 Storage ~94 KB uncompressed JS compressed delta (dcz) The edge caches the uncompressed body, stores it as a dictionary for future requests, compresses it against the previous version's dictionary, and serves the tiny delta to the browser. The response includes Use-As-Dictionary so the browser registers it for the next deploy.
Where the numbers come from
  • UncompressedPerformanceResourceTiming.decodedBodySize: full decoded JS size.
  • GzipPerformanceResourceTiming.transferSize from the first (non-dictionary) response.
  • DCZPerformanceResourceTiming.transferSize when dictionary compression is active. Encoding is detected by transfer size; you can also verify Content-Encoding: dcz in DevTools > Network tab.
  • Fetch timeperformance.now() delta from <script> tag insertion to script execution. During this window, the visualization goes greyscale. Fetch time may vary depending on whether the asset is a CDN cache hit or miss.
Test with curl

Test dictionary compression without a browser. Requires curl, openssl, and python3.

ORIGIN="https://canicompress.com"
CB=$(date +%s)

# Get two recent deploys from the manifest
MANIFEST=$(curl -s "$ORIGIN/manifest.json")
PREV=$(echo "$MANIFEST" | python3 -c \
  "import json,sys;print(json.load(sys.stdin)['recent_deploys'][1]['path'])")
CURR=$(echo "$MANIFEST" | python3 -c \
  "import json,sys;print(json.load(sys.stdin)['recent_deploys'][0]['path'])")

# Seed the previous deploy (stores it as a dictionary on the edge)
curl -s -o /dev/null "$ORIGIN$PREV?t=${CB}a" -H 'Accept-Encoding: dcz, gzip'
sleep 2

# Get its SHA-256 hash and dictionary ID
HASH=$(curl -s "$ORIGIN$PREV?t=${CB}a" -H 'Accept-Encoding: identity' \
  | openssl dgst -sha256 -binary | base64)
ID=$(curl -s -D - -o /dev/null "$ORIGIN$PREV?t=${CB}a" \
  -H 'Accept-Encoding: dcz, gzip' 2>>&1 \
  | grep '^use-as-dictionary:' \
  | sed 's/.*id="\([^"]*\)".*/\1/' | tr -d '\r')

# Compare: gzip (no dictionary) vs dcz (with dictionary)
echo "=== Gzip ==="
curl -s -o /dev/null -w 'size: %{size_download}B  time: %{time_total}s  ttfb: %{time_starttransfer}s\n' \
  "$ORIGIN$CURR?t=${CB}gzip" -H 'Accept-Encoding: gzip'

echo "=== DCZ ==="
curl -s -o /dev/null -w 'size: %{size_download}B  time: %{time_total}s  ttfb: %{time_starttransfer}s\n' \
  "$ORIGIN$CURR?t=${CB}dcz" \
  -H "Accept-Encoding: dcz, gzip" \
  -H "Available-Dictionary: :$HASH:" \
  -H "Dictionary-ID: \"$ID\""

Expected output:

=== Gzip ===
size: 29795B  time: 0.374s  ttfb: 0.362s
=== DCZ ===
size: 159B  time: 0.428s  ttfb: 0.377s
About the visualization

The background is a Wang tiling rendered as Truchet quarter-circle arcs, masked to the Cloudflare logo. Wang tiles are square tiles with colored edges, arranged so adjacent edges match — without rotating or flipping the tiles themselves.

While in theoretical computer science, Wang tiling is proven to be able to simulate a Turing machine, in tile-based games, Wang tiling is useful for procedural map generation. The concept of tilesets in these games is essentially a dictionary compression strategy: store a small set of unique tiles that are heavily duplicated at render time.

Troubleshooting
  • TLS-intercepting proxies: Some browsers like Chrome detect the use of TLS-intercepting proxies (Cloudflare WARP, corporate proxies) and will avoid sending dictionary transport headers when they are active. Disable them for this demo.
  • Browser requirements: Chrome 130+ or Edge 130+. Verify the feature is enabled at chrome://flags/#enable-compression-dictionary-transport (or edge://flags/ for Edge).
  • Multiple tabs/windows: Opening the same demo in multiple windows can cause browser cache interference, resulting in transferSize=0 readings. Use a single window.
  • "Disable cache" in DevTools must be OFF for dictionaries to be stored and used.
  • Check stored dictionaries: Inspect stored dictionaries at chrome://net-internals/#sharedDictionary (or edge://net-internals/ for Edge).