🎉 Introducing Edgio v6 which supports Node.js v16. Learn how to upgrade. 🎉
Edgio
Edgio

Compression

This guide covers the Edgio response compression support.

Accept-Encoding

When requesting data via HTTP from the Edgio servers, browsers include the accept-encoding header to indicate which data compression formats the browser supports. Modern browsers accept multiple compression formats, Accept-Encoding Header Details are here. This header is required by Edgio to trigger compression of responses.

Compression Support

Edgio supports:

  • gzip for all versions
  • br (Brotli) for versions >= 4.11.0

Implications on Caching

accept-encoding header is taken into account for splitting the cache by default. Expect different cache(s) for different accept-encoding header(s) for otherwise an identical request.

Gzip compression support

Gzip is supported in the following ways:

  • Pass-through of upstream Gzip responses if the browser accepts Gzip.
  • Encoding of upstream non-encoded responses if the browsers accepts Gzip or Gzip and Brotli.

Brotli compression support

Brotli is supported in the following ways:

  • Pass-through of upstream Brotli responses if the browser accepts Brotli.
  • Encoding of upstream non-encoded responses if the browsers only accepts Brotli.

Enabling Brotli compression

To enable Brotli (br) compression you need to ensure your project uses a version of @edgio >= 4.11.0. To upgrade @edgio to the latest version in your project use edgio use latest and redeploy your project.

What is Compressed?

When Edgio servers receive a request they inspect the accept-encoding header. The following logic is used to determine response compression:

  • If the response is not a compressible type, return uncompressed.
  • Else if no compression is accepted, then request no accepted encoding upstream and pass-through uncompressed upstream response.
  • Else if Brotli is supported (@edgio >= 4.11.0) then:
    • If br and gzip are both accepted, then request br, gzip upstream and then:
      • If upstream returned uncompressed response, compress with gzip.
      • Pass-through the upstream response in all other cases.
    • Else if only br is accepted, then request br upstream and then:
      • If upstream returned uncompressed response, compress with br.
      • Pass-through the upstream br upstream response.
    • Else (only gzip is accepted), then request gzip upstream and then:
      • If upstream returned uncompressed response, compress with gzip.
      • Pass-through the upstream gzip upstream response.
  • Else (only gzip is accepted, no Brotli support), then:
    • If upstream returned uncompressed response, compress with gzip.
    • Pass-through the upstream gzip upstream response.

Compressible Types

A response is considered compressible if the content-type contains one of these strings:

  • text/html
  • application/x-javascript
  • text/css
  • application/javascript
  • text/javascript
  • application/json
  • application/vnd.ms-fontobject
  • application/x-font-opentype
  • application/x-font-truetype
  • application/x-font-ttf
  • application/xml
  • font/eot
  • font/opentype
  • font/otf
  • image/svg+xml
  • image/vnd.microsoft.icon
  • text/plain
  • text/xml

or the url ends in one of these file extensions:

  • .css
  • .js
  • .html
  • .eot
  • .ico
  • .otf
  • .ttf
  • .json
  • .svg

Applying Brotli compression in serverless

Edgio serverless supports Brotli encoding starting with version 4.14.0 but, as described above, only for the content types recognized as compressible by the platform and if the browsers only accepts Brotli.

If you wish to implement a custom criteria to apply the Brotli compression yourself, you can do this by leveraging the built-in brotliCompressSync.

JavaScript
1import { brotliCompressSync } from 'zlib'
2
3const BROTLI_ENCODING_REGEX = /\bbr\b/
4
5// This function will respond with Brotli encoded body if the user agent
6// accepts Brotli.
7// Prior to invoking this function, evaluate all the custom criteria that you want to apply
8// (e.g. content type, caching, size of the response, etc). If all those are satisfied then
9// invoke this function which will then check if the downstream is Brotli compatible and
10// if so compress the body and respond with it, returning true, otherwise returning false.
11// You can of course optimize this to first check the downstream compatibility
12// before even considering other criteria.
13const sendBrotliEncoded = (req, res, body) => {
14 const acceptEncoding = req.getHeader('accept-encoding')
15 const acceptBrotliEncoding = BROTLI_ENCODING_REGEX.test(acceptEncoding)
16 if (!acceptBrotliEncoding) {
17 return false
18 }
19
20 const encodedBody = brotliCompressSync(Buffer.from(body))
21 res.setHeader('content-length', Buffer.byteLength(encodedBody))
22 res.setHeader('content-encoding', 'br')
23 res.send(encodedBody)
24 return true
25}

You would need to invoke the above just prior to sending back the response, similar to this:

JavaScript
1const useBrotliEncoding = /* Evaluate all the custom criteria that you would like to apply */;
2 if (!useBrotliEncoding || !sendBrotliEncoded(req, res, body)) {
3 res.send(body)
4 }