1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
---
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>`][picture]
element wrapped in a [`<figure>`][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>`][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.png`
* [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.
[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"
|