--- slug: media-shrinkage title: "Media Shrinkage" date: "2022-01-28T08:54:25-04:00" tables: shrinkage: cols: - id: "text" name: "Description" - id: "size" name: "Total Size (kB)" tip: "Total number of bytes transferred for an uncached front page load with Chrome." align: "right" - id: "percent" name: "Reduction (%)" tip: "Size reduction relative to baseline." align: "right" rows: - text: "Baseline uncached front page load" size: "596 kB" percent: "0%" - text: "WebP and minified SVGs" size: "324 kB" percent: "45%" - text: "WebP, minified SVGs, and mod\\_deflate update" size: "**185 kB**" percent: "**68%**" --- Recently I made the following site improvements: 1. Minified [SVGs][svg] with [minify][]. 2. Created lossless [WebPs][webp] of [PNGs][png] in recent content. 3. Created a [Hugo shortcode][shortcode] for the [``][picture] element wrapped in a [`
`][figure]. 5. Updated bitmap images in recent content to default to [WebP][] with a fallback to [PNG][] ([progressive enhancement][]). 6. Configured [mod\_deflate][mod_deflate] to compress [SVGs][svg] (see note about [BREACH][] below). 7. Enabled [HTTP/2][] (how did miss I this before?). 8. Added a [Cache-Control][] header for static style, script, and image assets. **Note:** Using [HTTP compression][] ([mod\_deflate][mod_deflate], [mod\_brotli][mod_brotli], etc) with [dynamic web pages][] can expose you to a [BREACH][] attack. This site is [statically generated][] (via [Hugo][]) so [BREACH][] is not an issue. ### Results 68% cumulative reduction in the total size of an uncached front page load in [Chrome][]: {{< table "shrinkage" >}} ### Notes * I will post later about the [progressive enhancement][] friendly [`
`][figure] [shortcode][]. * The [minify][] command is a thin wrapper around the excellent [tdewolff/minify library for Go][tdewolff-minify]. * I also investigated [AVIF][]. Better compression than [WebP][], worse tool and browser support. Will investigate again later. * Convert [PNG][] to lossless [WebP][] with [ImageMagick][]: `convert -quality 100 -define webp:lossless=true src.png dst.webp` * [Apache][] [mod\_deflate][mod_deflate] config: `AddOutputFilterByType image/svg+xml` * [HTTP/2][] in [Apache][]: Install [mod\_http2][mod_http2] and add `Protocols h2 http/1.1` to the [Apache][] config. You should also switch from [mpm\_prefork][mpm_prefork] to [mpm\_event][mpm_event] or [mpm\_worker][mpm_worker], but if you're using a non-threadsafe module like [mod\_php][mod_php] then this will give you some grief. * [Debian][]: Add `image/webp webp` to `/etc/mime.types`. **Update (2022-01-29):** Small formatting, grammar, and spelling fixes. Added [HTTP/2][] note, [Cache-Control][] note, [BREACH][] warning, and [tdewolff/minify][tdewolff-minify] link. **Update (2022-08-18):** Fixed typo in `convert` command. [svg]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics "Scalable Vector Graphics" [minify]: https://github.com/tdewolff/minify/tree/master/cmd/minify "Command-line SVG, JavaScript, HTML, and CSS minifier." [webp]: https://en.wikipedia.org/wiki/WebP "WebP image format." [png]: https://en.wikipedia.org/wiki/Portable_Network_Graphics "Portable Network Graphics" [shortcode]: https://gohugo.io/content-management/shortcodes/ "Simple snippets in content files calling built-in or custom templates" [figure]: https://gohugo.io/content-management/shortcodes/#figure "Hugo figure shortcode" [progressive enhancement]: https://en.wikipedia.org/wiki/Progressive_enhancement "Progressive enhancement" [picture]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture "picture HTML element" [figure]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure "figure HTML element" [mod_deflate]: https://httpd.apache.org/docs/current/mod/mod_deflate.html "Apache DEFLATE compression output filter." [chrome]: https://www.google.com/chrome "Google Chrome web browser." [avif]: https://en.wikipedia.org/wiki/AVIF "AV1 Image Format" [debian]: https://www.debian.org/ "Debian Linux distribution." [imagemagick]: https://imagemagick.org/ "Command-line image conversion tools." [apache]: https://httpd.apache.org/ "Apache web server." [breach]: https://en.wikipedia.org/wiki/BREACH "HTTP compression security vulnerability that leaks information over TLS connections." [http compression]: https://en.wikipedia.org/wiki/HTTP_compression "HTTP compression" [statically generated]: https://en.wikipedia.org/wiki/Static_web_page "Statically generated web page" [hugo]: https://gohugo.io/ "Hugo static site generator" [mod_brotli]: https://httpd.apache.org/docs/trunk/mod/mod_brotli.html "Apache brotli compression output filter." [dynamic web pages]: https://en.wikipedia.org/wiki/Dynamic_web_page "Dynamically generated web page" [tdewolff-minify]: https://github.com/tdewolff/minify "SVG, JavaScript, JSON, HTML, and CSS minification library for Go." [go]: https://golang.org/ "Go programming language" [http/2]: https://en.wikipedia.org/wiki/HTTP/2 "HyperText Transfer Protocol, version 2" [mod_http2]: https://httpd.apache.org/docs/2.4/howto/http2.html "Apache HTTP/2 module" [mpm_event]: https://httpd.apache.org/docs/2.4/mod/event.html "Apache multi-processing module that uses worker threads. Newer than mpm-worker." [mpm_worker]: https://httpd.apache.org/docs/2.4/mod/worker.html "Apache multi-processing module that uses worker threads." [mpm_prefork]: https://httpd.apache.org/docs/2.4/mod/prefork.html "Apache multi-processing module that uses pre-forked processes." [mod_php]: https://cwiki.apache.org/confluence/display/httpd/php "PHP module for Apache" [vhost]: https://httpd.apache.org/docs/2.4/vhosts/ "Apache virtual host" [cache-control]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control "Cache-Control HTTP header"