{"id":3307,"date":"2020-01-24T11:58:47","date_gmt":"2020-01-24T09:58:47","guid":{"rendered":"https:\/\/blog.tomayac.com\/2020\/01\/24\/brotli-compression-with-mod-pagespeed-and-ngx-pagespeed\/"},"modified":"2020-01-24T11:58:47","modified_gmt":"2020-01-24T09:58:47","slug":"brotli-compression-with-mod_pagespeed-and-ngx_pagespeed","status":"publish","type":"post","link":"https:\/\/tomayac.com\/wordpress\/2020\/01\/24\/brotli-compression-with-mod_pagespeed-and-ngx_pagespeed\/","title":{"rendered":"Brotli Compression with mod_pagespeed and ngx_pagespeed"},"content":{"rendered":"\n\t\t\t<p>The <a href=\"https:\/\/www.modpagespeed.com\/\">PageSpeed<\/a> modules\n(not to be confused with the\n<a href=\"https:\/\/developers.google.com\/speed\/pagespeed\/insights\/\">PageSpeed Insights<\/a>\nsite analysis service),\nare open-source webserver modules that optimize your site automatically.\nNamely, there is <a href=\"https:\/\/github.com\/apache\/incubator-pagespeed-mod\">mod_pagespeed<\/a>\nfor the <a href=\"https:\/\/httpd.apache.org\/\">Apache<\/a> server and\n<a href=\"https:\/\/github.com\/apache\/incubator-pagespeed-ngx\">ngx_pagespeed<\/a>\nfor the <a href=\"https:\/\/www.nginx.com\/\">Nginx<\/a> server.\nFor example, PageSpeed can automatically create WebP versions for all your image resources,\nand conditionally <em>only<\/em> serve the format to clients that accept <code>image\/webp<\/code>.\nI use it on this very blog, inspect a request to <a href=\"https:\/\/blog.tomayac.com\/images\/thomas_steiner_small.jpg\">any JPEG image<\/a>\nand see how on supporting browsers it gets served as WebP.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/jpg-to-webp.png\" alt=\"Chrome DevTools showing a request for a JPEG image that gets served as WebP\"><\/p>\n<h2 id=\"the-impact-of-brotli-compression\">The impact of Brotli compression <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2020\/01\/24\/brotli-compression-with-mod-pagespeed-and-ngx-pagespeed\/#the-impact-of-brotli-compression\">\u2693<\/a><\/h2>\n<p>When it comes to compression, <a href=\"https:\/\/github.com\/google\/brotli\">Brotli<\/a> really makes a difference.\nBrotli compression is only supported over HTTPS and is requested by clients\nby including <code>br<\/code> in the <code>accept-encoding<\/code> header.\nIn practice, Chrome sends\n<a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/master:net\/url_request\/url_request_http_job.cc;l=525-527\"><code>accept-encoding: gzip, deflate, br<\/code><\/a>.\nAs an example for the positive impact compared to gzip, check out a recent case study shared by\n<a href=\"https:\/\/twitter.com\/addyosmani\/status\/1220085588948185088\">Addy Osmani<\/a>\nin which the web team of the hotel company <a href=\"https:\/\/www.treebo.com\/\">Treebo<\/a> share their\n<a href=\"https:\/\/tech.treebo.com\/a-tale-of-brotli-compression-bcb071d9780a\">Tale of Brotli Compression<\/a>.<\/p>\n<h2 id=\"pagespeed-does-not-support-brotli-yet\">PageSpeed does not support Brotli yet <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2020\/01\/24\/brotli-compression-with-mod-pagespeed-and-ngx-pagespeed\/#pagespeed-does-not-support-brotli-yet\">\u2693<\/a><\/h2>\n<p>While both webservers support Brotli compression out of the box,\nApache via <a href=\"https:\/\/httpd.apache.org\/docs\/trunk\/mod\/mod_brotli.html\">mod_brotli<\/a>\nand Nginx via <a href=\"https:\/\/github.com\/google\/ngx_brotli\">ngx_brotli<\/a>,\none thing that PageSpeed is currently missing is native Brotli support,\ncausing resources that went through any PageSpeed optimization step to not be Brotli-encoded \ud83d\ude14.\nPageSpeed is really smart about compression in general, for instance,\nit always\n<a href=\"https:\/\/www.modpagespeed.com\/doc\/configuration#output_filter\">automatically enables <code>mod_deflate<\/code> for compression<\/a>,\noptionally <a href=\"https:\/\/www.modpagespeed.com\/doc\/system#fetch_with_gzip\">adds an <code>accept-encoding: gzip<\/code> header to requests that lack it<\/a>,\nand <a href=\"https:\/\/www.modpagespeed.com\/doc\/system#gzip_cache\">automatically <code>gzip<\/code>s compressable resources as they are stored in the cache<\/a>,\nbut Brotli support is just not there yet.\nThe good news is that it is being worked on,\n<a href=\"https:\/\/github.com\/apache\/incubator-pagespeed-mod\/issues\/1148\">GitHub Issue #1148<\/a>\ntracks the effort.<\/p>\n<h2 id=\"making-brotli-work-with-pagespeed\">Making Brotli work with PageSpeed <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2020\/01\/24\/brotli-compression-with-mod-pagespeed-and-ngx-pagespeed\/#making-brotli-work-with-pagespeed\">\u2693<\/a><\/h2>\n<p>The even better news is that while we are waiting for native Brotli support in PageSpeed,\nwe can just outsource Brotli compression to the underlying webserver.\nTo do so, simply disable PageSpeed's HTTPCache Compression.\nQuoting from the <a href=\"https:\/\/www.modpagespeed.com\/doc\/system#gzip_cache\">documentation<\/a>:<\/p>\n<blockquote>\n<p>To configure cache compression, set <code>HttpCacheCompressionLevel<\/code> to values between <code>-1<\/code> and <code>9<\/code>,\nwith <code>0<\/code> being off, <code>-1<\/code> being <code>gzip<\/code>'s default compression, and <code>9<\/code> being maximum compression.<\/p>\n<\/blockquote>\n<p>\ud83d\udce2 So to make PageSpeed work with Brotli, what you want in your\n<a href=\"https:\/\/github.com\/apache\/incubator-pagespeed-mod\/blob\/master\/install\/common\/pagespeed.conf.template\"><code>pagespeed.conf<\/code><\/a>\nfile is a new line:<\/p>\n<pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Disable PageSpeed's gzip compression, so the server's<\/span><br><span class=\"token comment\"># native Brotli compression kicks in via `mod_brotli`<\/span><br><span class=\"token comment\"># or `ngx_brotli`.<\/span><br>ModPagespeedHttpCacheCompressionLevel <span class=\"token number\">0<\/span><\/code><\/pre>\n<p>One thing to have an eye on is server load.\nBrotli is more demanding than gzip, so for your static resources, you probably want to\n<a href=\"https:\/\/httpd.apache.org\/docs\/trunk\/mod\/mod_brotli.html#precompressed\">serve pre-compressed content<\/a>\nwherever possible, and for the odd chance of\n<a href=\"https:\/\/github.com\/mozilla\/standards-positions\/issues\/105#issuecomment-559315997\">when you are Facebook, maybe disable Brotli for your dynamic resources<\/a>.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/pagespeed.png\" alt=\"Chrome DevTools Network panel showing traffic for this blog with resources served Brotli-compressed highlighted\"><\/p>\n<p>Happy Brotli serving, and, by the way, in case you ever wondered,\nBrotli is a \ud83c\udde8\ud83c\udded Swiss German word for a bread roll and literally means &quot;small bread&quot;.<\/p>\n\n\t\t\t<p>\n\t\t\t\t<img alt=\"Thomas Steiner\" width=\"32\" height=\"32\" src=\"https:\/\/blog.tomayac.com\/feed.php?dl=https%3A%2F%2Fblog.tomayac.com%2F2020%2F01%2F24%2Fbrotli-compression-with-mod-pagespeed-and-ngx-pagespeed%2F&dp=%2F2020%2F01%2F24%2Fbrotli-compression-with-mod-pagespeed-and-ngx-pagespeed%2F&dt=Brotli%20Compression%20with%20mod_pagespeed%20and%20ngx_pagespeed\" alt=\"\">\n\t\t\t\t<br\/>This post appeared first on <a href=\"https:\/\/blog.tomayac.com\/2020\/01\/24\/brotli-compression-with-mod-pagespeed-and-ngx-pagespeed\/\">https:\/\/blog.tomayac.com\/2020\/01\/24\/brotli-compression-with-mod-pagespeed-and-ngx-pagespeed\/<\/a>.\n\t\t\t<\/p>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\t\t\tThe PageSpeed modules<br \/>\n(not to be confused with the<br \/>\nPageSpeed Insights<br \/>\nsite analysis service),<br \/>\nare open-source webserver modules that optimize your site automatically.<br \/>\nNamely, there is mod_pagespeed<br \/>\nfor the Apache server and<br \/>\nngx_pagespeed<br \/>\nfor the Ng&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"intlwemo_wallet_address":"","footnotes":""},"categories":[],"tags":[],"class_list":["post-3307","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts\/3307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/comments?post=3307"}],"version-history":[{"count":3,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts\/3307\/revisions"}],"predecessor-version":[{"id":3308,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts\/3307\/revisions\/3308"}],"wp:attachment":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/media?parent=3307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/categories?post=3307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/tags?post=3307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}