Compression
deflate-raw, and only when it helps. The choice is dictated by what a stateless loader can decompress with zero bytes of its own code.
Algorithm
When bit 1 of flags (FLAG_COMPRESSED, 0b10) is set, the body — or, if also encrypted, the plaintext inside the envelope — is a raw DEFLATE stream as defined in RFC 1951, with no zlib (RFC 1950) or gzip (RFC 1952) wrapper. This is exactly the "deflate-raw" format of the WHATWG Compression Streams API.
- Encoders MUST set the flag only if the compressed output is strictly shorter than the input. Tiny payloads and already-compressed data are stored raw.
- Decoders MUST accept any conforming DEFLATE stream regardless of the compression level or implementation that produced it. Test vectors for compressed bodies are therefore informative, not byte-exact requirements.
- The
lengthandcrc32header fields describe the compressed bytes. The decompressed size is not stored; decoders learn it by decompressing.
Why not Brotli or Zstandard?
Brotli typically beats DEFLATE by 15–25 % on HTML, and its built-in dictionary is tuned for exactly this content. But the loader (§8) must decompress using only APIs already present in the browser, and as of this writing DecompressionStream supports gzip, deflate and deflate-raw only. Shipping a Brotli decoder would cost far more bytes than it saves on any payload that fits in a favicon. If browsers add "brotli" to Compression Streams, a future flag bit can adopt it without breaking version 1 decoders (§12).
Reference implementation
async function pipe(bytes: Uint8Array, stream: ReadableWritablePair<Uint8Array, Uint8Array>) {
const out = new Blob([bytes]).stream().pipeThrough(stream)
return new Uint8Array(await new Response(out).arrayBuffer())
}
export const deflate = (b: Uint8Array) => pipe(b, new CompressionStream('deflate-raw'))
export const inflate = (b: Uint8Array) => pipe(b, new DecompressionStream('deflate-raw'))Measuring the ratio
User-facing statistics such as the Showcase "compression ratio" are defined as rawBytes / bodyBytes, where rawBytes is the UTF-8 length of the original payload and bodyBytes is the body length recorded in the header. The 12-byte header and the PNG container overhead are excluded so that the number reflects the codec, not the carrier.