<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/main.f00fa164b15c74f82cbe391a45ec306d833cc5d26082438afd698069f13cae94.xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Images on Oli's Blog</title><link>https://oli.fyi/tags/images/</link><description>Recent content in Images on Oli's Blog</description><generator>Hugo 0.162.0</generator><language>en-AU</language><copyright>Oli</copyright><pubDate>Mon, 01 Jun 2026 00:00:00 +0200</pubDate><lastBuildDate>Wed, 03 Jun 2026 21:34:29 +0200</lastBuildDate><atom:link href="https://oli.fyi/tags/images/index.xml" rel="self" type="application/rss+xml"/><item><title>AVIF pictures with Hugo</title><link>https://oli.fyi/2026/avif-pictures-with-hugo/</link><pubDate>Mon, 01 Jun 2026 00:00:00 +0200</pubDate><guid>https://oli.fyi/2026/avif-pictures-with-hugo/</guid><description>&lt;p&gt;Hugo &lt;a href="https://github.com/gohugoio/hugo/releases/tag/v0.162.0"&gt;recently introduced AVIF support for their image processing&lt;/a&gt;, something I have been waiting for quite a while. I was excited because &lt;a href="https://www.ctrl.blog/entry/webp-avif-comparison.html"&gt;AVIF is generally considered more efficient than WEBP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at an example from the &lt;a href="https://oli.fyi/2024/the-uci-road-cycling-elite-mens-race-in-pictures/"&gt;Cycling race in 2024&lt;/a&gt;:&lt;/p&gt;</description><content:encoded><![CDATA[<p>Hugo <a href="https://github.com/gohugoio/hugo/releases/tag/v0.162.0">recently introduced AVIF support for their image processing</a>, something I have been waiting for quite a while. I was excited because <a href="https://www.ctrl.blog/entry/webp-avif-comparison.html">AVIF is generally considered more efficient than WEBP</a>.</p>
<p>Let&rsquo;s look at an example from the <a href="/2024/the-uci-road-cycling-elite-mens-race-in-pictures/">Cycling race in 2024</a>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#f92672">picture</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;w-[100%] ml-[0%]&#34;</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">source</span> <span style="color:#a6e22e">srcset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_b7579d70d40992b1.avif 1x, /2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_af0dede09f13f635.avif 2x, /2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_ba489f112ee6caa8.avif 3x&#34;</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">image/avif</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">source</span> <span style="color:#a6e22e">srcset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_467d840e33513384.webp 1x, /2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_a9d99390b59f3129.webp 2x, /2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_910d856310b4bf99.webp 3x&#34;</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">image/webp</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">source</span> <span style="color:#a6e22e">srcset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_753a9b9e6ea8568f.jpg 1x, /2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_4cc7e3233a05cc3.jpg 2x, /2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1_hu_1cb7e3f7cd42a85b.jpg 3x&#34;</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">image/jpeg</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">/2024/the-uci-road-cycling-elite-mens-race-in-pictures/schwantenmos-1.75ff9b52d4278c6fefea71c81fa4c87c44f4e11aabbf93f0fd09b52e519cca0d.jpg</span> <span style="color:#a6e22e">alt</span> <span style="color:#a6e22e">width</span><span style="color:#f92672">=</span><span style="color:#e6db74">3780</span> <span style="color:#a6e22e">height</span><span style="color:#f92672">=</span><span style="color:#e6db74">2088</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">picture</span>&gt;
</span></span></code></pre></div><p>The <code>&lt;picture&gt;</code> element with multiple <code>&lt;source&gt;</code> tags is doing the heavy lifting here. The browser picks the first format it supports: AVIF for modern browsers, WEBP as a fallback, and good old JPEG for the holdouts.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> Progressive enhancement at its finest.</p>
<h2 id="the-numbers-in-theory">The numbers (in theory)</h2>
<p>How much better is AVIF, really? According to <a href="https://www.ctrl.blog/entry/webp-avif-comparison.html">Daniel Aleksandersen&rsquo;s comparison</a>, AVIF achieves a median file size reduction of <strong>50.3%</strong> compared to JPEG at equivalent visual quality. WEBP? Only 31.5%. And here&rsquo;s the kicker: AVIF outperformed both JPEG and WEBP for <em>every single image</em> in the test. Not most. Every.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<p>For a photo-heavy blog like this sometimes is, that&rsquo;s significant. Smaller files mean faster loads, less bandwidth, and happier readers on slow connections.</p>
<h2 id="the-quality-problem-in-practice">The quality problem (in practice)</h2>
<p>Here&rsquo;s the catch: Hugo&rsquo;s AVIF files are currently larger than WEBP, not smaller. Wait, what?</p>
<p>The issue is <a href="https://github.com/gohugoio/hugo/issues/14957">how Hugo handles quality settings</a>. Hugo uses a default quality of 75 for all formats: JPEG, WEBP, and AVIF alike. But these scales aren&rsquo;t perceptually equivalent. WEBP&rsquo;s quality 75 is its conventional &ldquo;good lossy&rdquo; sweet spot. AVIF, on the other hand, was designed with a default of around 60, and quality 60–70 in AVIF is considered comparable to WEBP at 75.</p>
<p>By using quality 75 for AVIF, Hugo is essentially producing higher-quality-than-necessary images, which means larger files. The fix would be per-format quality settings, something that&rsquo;s <a href="https://github.com/gohugoio/hugo/issues/14957">being discussed</a> but not yet implemented.</p>
<p>For now, you can manually set a lower quality when processing AVIF images, but it&rsquo;s not ideal. I&rsquo;m keeping an eye on that issue.</p>
<h2 id="speed-and-caching">Speed and caching</h2>
<p>I&rsquo;ve <a href="/2025/cloudflare-could-save-me-some-time-and-itself-some-money/">written before about optimising Hugo builds with Cloudflare</a>, and AVIF adds an interesting wrinkle. The encoding is slow—noticeably slower than WEBP or JPEG. Hugo&rsquo;s image processing now has to do more work, which means build times go up.</p>
<p>The solution? Move the build to GitHub Actions and just deploy the static files to Cloudflare. Cloudflare&rsquo;s build caching is limited and fiddly, but GitHub Actions has <a href="https://github.com/actions/cache">proper configurable caching</a> that actually works. Cache the <code>resources</code> folder between builds, and Hugo won&rsquo;t re-encode images that haven&rsquo;t changed. Subsequent builds go from &ldquo;coffee break&rdquo; to &ldquo;blink and you&rsquo;ll miss it.&rdquo;<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
<h2 id="browser-support">Browser support</h2>
<p>AVIF support is <a href="https://caniuse.com/avif">essentially universal now</a>. Chrome, Firefox, Safari, Edge—they all handle it. The only stragglers are older browser versions and some niche cases. That&rsquo;s why the <code>&lt;picture&gt;</code> fallback chain matters: you serve the best format to browsers that can handle it and gracefully degrade for the rest.</p>
<h2 id="was-it-worth-it">Was it worth it?</h2>
<p>Mostly. The quality is excellent, the implementation in Hugo is straightforward, and once the per-format quality settings land, the file size savings should be real. Right now it&rsquo;s a bit of a wash, or even a regression, compared to WEBP, but the foundation is there.</p>
<p>The only downside is build time, and that&rsquo;s a one-time cost per image. For a static site that rebuilds occasionally, it&rsquo;s a non-issue. For a site with thousands of images and frequent deploys, maybe budget some extra CI minutes.</p>
<p>Now if only Hugo would add JPEG XL support.<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Yes, there are still people using browsers that don&rsquo;t support WEBP. I don&rsquo;t understand them either, but I respect their commitment to the old ways.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>The comparison used DSSIM (structural dissimilarity) to ensure equivalent visual quality across formats. Science!&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>The trick is caching <code>resources/_gen/images</code>. Hugo stores all processed images there, keyed by a hash of the source and processing options. As long as that folder persists between builds, you only pay the AVIF encoding cost once per image.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>JPEG XL is arguably even better than AVIF in some ways, but Hugo doesn&rsquo;t support it at all. And browser support is complicated. Safari supports it, Chrome removed it, Firefox is thinking about it. The format wars never end.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item></channel></rss>