HTTP compression and incremental rendering

TL;DR: HTTP compression can delay rendering of web resources

HTTP permits content to be served with different encodings, some of which can be used to compress [1] the data volume transferred over the network, which has become a frequent suggestion [2] towards optimising websites for performance. It turns out that the deflation phase of the two most widely used (de)compression algorithms used on the web today, gzip [3] and brotli [4], require some compressed input data before they output the first byte, with brotli requiring much more than gzip.

compress

One can imagine the decompression algorithm outputting the uncompressed data only once enough compressed input data has been read, such as control structures, dictionaries and, of course, the first block of compressed data.

The decompression delay introduced by these algorithms is at odds with incremental rendering [5] implemented by main stream browsers, where the browser will show a page building up as its being downloaded.

I wanted to get a feeling for the magnitude of the compression delay and performed a simple experiment.

First I downloaded the imdb home page HTML to a file:

curl https://www.imdb.com/ > imdb.html

Then I compressed the file into two versions, one with gzip, one with brotli:

gzip imdb.html
brotli imdb.html

Then I fed the heading of the compressed files into the decompressor until it would show some useful output:

dd if=imdb.html.gz ibs=1 count=1000 | gzip -d -c
dd if=imdb.html.br ibs=1 count=1000 | brotli -d -c

“dd if=imdb.html.gz ibs=1 count=1000” prints the first 1000 bytes of imdb.html.gz

In my experiments, gzip needs 100 bytes of compressed input until the first output, while brotli required more than 40KB compressed input (since the IMDB homepage compressed to less than that, I repeated the experiment with larger input files).

Over a GPRS [6] connection which can deliver about 4KByte/sec, both non-compressed and gzip compressed content would start rendering within the first second while brotli compressed content would require around than 10 seconds. Both cases don’t consider the time to establish the radio link and TCP connection and assume no error-induced delays (e.g. packet loss).

When should HTTP compression be used?

I think that the specifics of each situation outweigh the benefit of generalised advice. Whenever an incrementally rendered resource aids user experience, then that is a good candidate for a lighter compression scheme. Such resources are HTML pages and embedded frames, whereas images, Javascript libraries and CSS files are no use if downloaded partially and thus need to be delivered as a whole as fast as possible.

Counter-intuitively, users visiting a website over a fast network link would not notice much of a difference whether content was compressed or not, but the website operator would probably be able to reduce hosting costs by serving compressed content. A user visiting over a slow network link might however appreciate that a page is at least partially legible as soon as possible.

Overall, good application design that caters for the needs of its users cannot be replaced by any compression technique.

Resources

[1] HTTP compression on Wikipedia
https://en.wikipedia.org/wiki/HTTP_compression

[2] Google web developer
https://developers.google.com/speed/docs/insights/EnableCompression

[3] gzip on Wikipedia
https://en.wikipedia.org/wiki/Gzip

[4] Brotli on Wikipedia
https://en.wikipedia.org/wiki/Brotli

[5] Incremental rendering on Wikipedia
https://en.wikipedia.org/wiki/Incremental_rendering

[6] GPRS on Wikipedia
https://en.wikipedia.org/wiki/General_Packet_Radio_Service

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s