Compression

Web Compression

Techniques for compressing web content to reduce data transfer size and improve performance.

Why web resources are compressed

Every webpage consists of resources downloaded from a web server to the browser. These include text, images, stylesheets that define the page's appearance, and scripts that provide interaction. After selecting an address, the browser sends a request, receives responses, and assembles the resources into a document it can display. The browser fetches these resources in multiple requests, and their combined size affects the time needed to download and display the page. Connection latency, available bandwidth, and processing time on the server and client also matter. describes these timings and the page's behavior while resources are being fetched. Variable mobile connections make the number of transferred bytes especially important.

Web compression reduces the amount of data transferred between a server and a browser. HTTP compression changes the representation sent over the network, while image compression changes the image file itself. A server can compress a text resource such as an HTML file before sending it, and the browser restores its original form after receiving it. The operation is lossless for text, so the parser receives the same characters after decoding. A smaller transfer reduces bandwidth use and can shorten page downloads. Content coding does not replace optimizing the resource itself, since its format, contents, and request count can be improved separately. The perceived result also depends on delivery order: a stylesheet can block the first render, and a script can require an earlier download. Compression reduces transfer, but it does not remove dependencies between resources or the browser's parsing cost.

HTTP content-coding negotiation

HTTP compression requires cooperation between the client and the server. The agreement is carried in . The client lists acceptable codings, and the server selects a representation for the request. The content negotiation process works as follows:

  1. The browser lists accepted codings:

    When a browser requests a resource, such as the main HTML file, it includes an Accept-Encoding header. Its value lists content codings that the client can receive. The client can also state a preference, for example gzip;q=0.8, where the quality parameter contributes to the server's choice.

    Accept-Encoding: gzip, deflate, br

    The example lists gzip, deflate, and br. Quality parameters can express client preferences, while the server selects a coding according to negotiation and its own configuration. A quality value of zero means that the client does not accept that coding. Without a suitable variant, the server can send the content without a coding.

  2. The server selects a representation:

    The server examines Accept-Encoding and compares it with its own configuration. It can compress text files such as HTML and CSS. It usually skips resources that are already compressed, such as JPEG images and ZIP archives, because another pass can increase size or processing cost.

  3. The server compresses and responds:

    If the server selects Brotli, it takes the requested file, such as index.html, and sends a compressed representation. The Content-Encoding header identifies the coding applied to the response content. It does not change the resource type, which is still described by the media type and the response semantics.

    Content-Encoding: br

    The value br tells the recipient to use Brotli to decode the content. If the server sends the content without a coding, it can omit this header.

    When the selected representation depends on a request header, a cache should also receive Vary: Accept-Encoding.

  4. The browser decodes the content:

    The browser reads Content-Encoding: br and decodes the Brotli stream. It can then parse and render the resulting HTML.

Negotiation lets the server select a representation supported by the client. The mechanism applies to each response whose content is encoded. When the response is cached, coded and uncoded variants must be distinguished using the Vary header. Coding is applied to the representation before it is sent, so the client must know the order of applied codings when a response uses more than one. A server should store each variant with its coding information so a cache does not return an unsupported representation.

Gzip and the DEFLATE format

Gzip is a widely supported HTTP content coding based on the lossless . DEFLATE combines repeated-sequence matching with statistical coding, making it suitable for text-based resources. The Gzip format also carries information needed to read the stream and check its integrity.

The Gzip process: DEFLATE

When a server compresses a text file like CSS or JavaScript with Gzip, it is performing a two-stage process:

  1. Finding repeated sequences with LZ77: The algorithm scans the input file and keeps a sliding window of recently processed data. When it finds an earlier sequence, it replaces it with a reference containing the match distance and length. In DEFLATE, a reference distance can reach 32 KiB, while a match length of at most 258 bytes is coded separately. Data without a match is stored as literals. HTML, CSS, and JavaScript files repeat items such as <div>, the class= attribute, and the word function.
  2. Huffman coding: The LZ77 output contains literals and references. Huffman coding analyzes symbol frequencies and assigns variable-length codes. Frequent symbols receive shorter codes and rare symbols longer ones, removing part of the remaining statistical redundancy. DEFLATE uses one Huffman code tree for literals and lengths and a separate tree for distances, so the two kinds of information can follow their own code distributions.

The size of a Gzip result depends on the content, its repetition, and encoder settings. Enabling this coding on the server reduces the transfer of text resources without changing their decoded content. For resources that change rarely, a server can prepare the compressed variant in advance so encoding does not occur for every request. The Gzip format has a header identifying the stream and a trailer containing a CRC-32 value and the input size modulo 2^32. These fields help detect some corruption and check the data length after decompression.

Brotli and its static dictionary

Developed by Google, is another content coding used with HTTP. It can produce a smaller result than Gzip for many text resources, while the cost and result depend on the settings and input data.

Brotli's static dictionary

Brotli uses repeated-sequence matching and entropy coding. An important component is its built-in static dictionary. The specification defines a dictionary of 122,784 bytes containing predefined strings and their forms. Dictionary entries also define permitted copy lengths from 4 to 24 bytes. The dictionary is known to both encoder and decoder, so it does not need to be sent with each resource. The encoder can reference such a string without a previous occurrence in the current file.

Gzip searches for matches in the data processed so far. Brotli can also reference its static dictionary, which helps with short resources that contain few internal repetitions. The dictionary includes predefined forms, so the encoder can match a fragment of a different length without placing it earlier in the file. References to predefined strings reduce the data needed for the representation.

Performance and Trade-offs

Brotli's output size depends on the content and quality settings. Compared with Gzip, it can produce a smaller representation and therefore fewer bytes to send to the client. Choosing a variant also requires considering server time, file size, and decoding work on the client.

Higher Brotli quality settings can increase the encoder's work. A server can prepare compressed variants of static resources in advance and send them according to content-coding negotiation. The variant should be stored with its coding information and used only for a client that accepts it. The recipient performs decoding on its own device, and that cost is separate from the time needed to prepare the server-side variant.

Asset optimization beyond transfer

Gzip and Brotli reduce the representation transferred over the network. Other optimization can reduce an asset before the server applies HTTP content coding. The two layers complement each other when a page is delivered.

Code minification

is a process that applies to text-based assets like HTML, CSS, and JavaScript. Developers write code with lots of whitespace, comments, and long, descriptive variable names to make it readable and maintainable for humans. However, a web browser does not need any of this to execute the code.

Minification tools parse the code and remove characters that the parser does not need, such as whitespace and comments. They can also shorten local variable and function names when the resource interface remains unchanged. They must retain separators that distinguish tokens or preserve code meaning. The minified file is shorter while retaining the behavior required by the browser. Source maps remain a separate resource for debugging. Fewer repeated characters can also improve the result of Gzip or Brotli.

Image and font optimization

Modern image formats such as WebP and AVIF can reduce image size relative to JPEG or PNG at comparable quality. WOFF2 and reduce the data in a font file. A subset can match the alphabet required by a page's language, while retaining every character that the page displays. Images and fonts are usually compressed by their own formats, so preparing them before transfer provides the largest gain.

Caching and conditional requests

When a user visits a page again, the browser checks its local . A Cache-Control header specifies how long a copy can be stored, for example with the max-age directive. A fresh copy lets the browser use the resource without another request.

After the copy expires, the browser can send a conditional request containing information about the version it has, for example an ETag or Last-Modified value. The server compares that information with the current representation and can respond with 304 Not Modified when the representation has not changed. The response does not send the full content again. The browser then uses its local file instead of downloading the entire content again. Combining caching with compression requires consistent version identifiers for every representation variant. When a file changes, the previous variant should be invalidated so the next request receives current content with the appropriate coding.

Related articles