<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Avif on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/avif/</link><description>Recent content in Avif on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Thu, 19 Feb 2026 17:00:00 +0200</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/avif/index.xml" rel="self" type="application/rss+xml"/><item><title>Optimisation webperf : AVIF et pré-compression pour le blog</title><link>https://blog.zwindler.fr/2026/02/19/optimisation-webperf-avif-precompression/</link><pubDate>Thu, 19 Feb 2026 17:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2026/02/19/optimisation-webperf-avif-precompression/</guid><description>&lt;img src="https://blog.zwindler.fr/2026/02/webperf0.webp" alt="Featured image of post Optimisation webperf : AVIF et pré-compression pour le blog" /&gt;&lt;p&gt;Ce blog a presque 16 ans d&amp;rsquo;existence. Sur cette période, j&amp;rsquo;ai accumulé plus de 530 articles avec plus de 2700 images. Il y a quelques années, j&amp;rsquo;avais commencé à taper des limites (notamment quand j&amp;rsquo;ai essayer Gitlab pages chez Froggit) en atteignant les 500 Mo de medias.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;avais fait une première passe d&amp;rsquo;optimisation, à grand coup de resize, &lt;code&gt;jpegoptim&lt;/code&gt; et &lt;code&gt;optipng&lt;/code&gt; et j&amp;rsquo;étais redescendu sous les 300 Mo. C&amp;rsquo;était pas mal, mais pas satisfaisant.&lt;/p&gt;
&lt;p&gt;Puis j&amp;rsquo;ai vu &lt;a class="link" href="https://blog.zwindler.fr/2026/02/13/recap-touraine-tech-2026-jour2/#au-secours--mes-images-pourrissent-mes-perfs" &gt;le talk d&amp;rsquo;Antoine Caron (slashgear) et Mathieu Mure à Touraine Tech 2026&lt;/a&gt; et j&amp;rsquo;ai enfin pris le temps de lâcher les &amp;ldquo;formats morts&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="un-peu-de-contexte"&gt;Un peu de contexte
&lt;/h2&gt;&lt;p&gt;Ça fait un moment que je bricole l&amp;rsquo;infra et les perfs de ce blog. Si ça vous intéresse, les épisodes précédents sont ici :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2019/12/24/ca-bouge-pas-mal-sur-le-blog/" &gt;Ça bouge pas mal sur le blog !&lt;/a&gt; (2019) - De 5s à 1s en virant Wordpress pour Hugo&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2025/01/15/ca-bouge-encore-sur-le-blog/" &gt;Ça bouge encore sur le blog&lt;/a&gt; (2025) - Nettoyage massif, retour auto-hébergé&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2023/08/01/automatiser-hugo-sans-github-action/" &gt;Automatiser son site Hugo sans Github Action ou Vercel&lt;/a&gt; - Le setup nginx + webhook actuel&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quand j&amp;rsquo;ai commencé ce round d&amp;rsquo;optimisation, la note PageSpeed de la page d&amp;rsquo;accueil tournait autour de 70-85 en mobile selon les articles. Pas dramatique, mais on peut faire mieux !&lt;/p&gt;
&lt;h2 id="le-talk-qui-a-tout-déclenché"&gt;Le talk qui a tout déclenché
&lt;/h2&gt;&lt;p&gt;À &lt;a class="link" href="https://blog.zwindler.fr/2026/02/13/recap-touraine-tech-2026-jour2/" &gt;Touraine Tech 2026&lt;/a&gt;, Antoine Caron et Mathieu Mure ont fait un talk très clair sur l&amp;rsquo;optimisation des images web, qui pourrissent les perfs des sites web aujourd&amp;rsquo;hui.&lt;/p&gt;
&lt;p&gt;Le message principal : les formats comme JPEG et PNG sont des &amp;ldquo;formats morts&amp;rdquo; (ou en tout cas vieillissants). À compression équivalente, les formats modernes comme AVIF prennent beaucoup moins de place, mais surtout, ils affichent des artefacts visuels bien moindres dans les hauts niveaux de compression.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;avais failli faire une migration vers le WebP il y a quelques années, puis j&amp;rsquo;avais laissé tomber, par flemme et après quelques soucis techniques dont je ne me souviens plus trop.&lt;/p&gt;
&lt;p&gt;Et finalement, c&amp;rsquo;est presque tant mieux, parce qu&amp;rsquo;avec AVIF, on peut compresser &lt;strong&gt;encore plus fort&lt;/strong&gt;, sans que ça se voit. C&amp;rsquo;est exactement ce qu&amp;rsquo;il me fallait.&lt;/p&gt;
&lt;p&gt;Side note : on m&amp;rsquo;a demandé une comparaison WebP vs AVIF, et Joseph a trouvé ça. C&amp;rsquo;est plutôt intéressant :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://elementor.com/blog/fr/avif-vs-webp-quel-format-dimage-regne-en-maitre-en-2024/" target="_blank" rel="noopener"
&gt;elementor blog - AVIF vs WebP : Quel format d’image règne en maître en 2024 ?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conversion-massive-en-avif"&gt;Conversion massive en AVIF
&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;ai donc écrit un script qui :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Redimensionne&lt;/strong&gt; les images trop grandes (&amp;gt; 1500px) pour les ramener à ~1 mégapixel&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Convertit en AVIF&lt;/strong&gt; avec &lt;code&gt;avifenc&lt;/code&gt; (qualité 50, speed 6)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Met à jour les références&lt;/strong&gt; dans tous les articles markdown&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Et je l&amp;rsquo;ai lancé année par année, de 2026 jusqu&amp;rsquo;à 2010.&lt;/p&gt;
&lt;h3 id="les-résultats"&gt;Les résultats
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Année&lt;/th&gt;
&lt;th&gt;Fichiers&lt;/th&gt;
&lt;th&gt;Originaux&lt;/th&gt;
&lt;th&gt;AVIF&lt;/th&gt;
&lt;th&gt;Réduction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2010&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;0.4 MiB&lt;/td&gt;
&lt;td&gt;0.1 MiB&lt;/td&gt;
&lt;td&gt;74%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2011&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;1.8 MiB&lt;/td&gt;
&lt;td&gt;0.7 MiB&lt;/td&gt;
&lt;td&gt;63%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;0.4 MiB&lt;/td&gt;
&lt;td&gt;0.1 MiB&lt;/td&gt;
&lt;td&gt;78%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2013&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.1 MiB&lt;/td&gt;
&lt;td&gt;0.1 MiB&lt;/td&gt;
&lt;td&gt;56%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2014&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;5.3 MiB&lt;/td&gt;
&lt;td&gt;1.0 MiB&lt;/td&gt;
&lt;td&gt;81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2015&lt;/td&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;10.7 MiB&lt;/td&gt;
&lt;td&gt;3.7 MiB&lt;/td&gt;
&lt;td&gt;65%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;231&lt;/td&gt;
&lt;td&gt;12.1 MiB&lt;/td&gt;
&lt;td&gt;4.1 MiB&lt;/td&gt;
&lt;td&gt;66%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;428&lt;/td&gt;
&lt;td&gt;23.7 MiB&lt;/td&gt;
&lt;td&gt;9.1 MiB&lt;/td&gt;
&lt;td&gt;62%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2018&lt;/td&gt;
&lt;td&gt;142&lt;/td&gt;
&lt;td&gt;7.5 MiB&lt;/td&gt;
&lt;td&gt;2.4 MiB&lt;/td&gt;
&lt;td&gt;68%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2019&lt;/td&gt;
&lt;td&gt;136&lt;/td&gt;
&lt;td&gt;12.1 MiB&lt;/td&gt;
&lt;td&gt;2.9 MiB&lt;/td&gt;
&lt;td&gt;76%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;228&lt;/td&gt;
&lt;td&gt;23.6 MiB&lt;/td&gt;
&lt;td&gt;5.6 MiB&lt;/td&gt;
&lt;td&gt;77%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2021&lt;/td&gt;
&lt;td&gt;187&lt;/td&gt;
&lt;td&gt;31.6 MiB&lt;/td&gt;
&lt;td&gt;4.8 MiB&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2022&lt;/td&gt;
&lt;td&gt;237&lt;/td&gt;
&lt;td&gt;29.2 MiB&lt;/td&gt;
&lt;td&gt;7.5 MiB&lt;/td&gt;
&lt;td&gt;74%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023&lt;/td&gt;
&lt;td&gt;253&lt;/td&gt;
&lt;td&gt;43.2 MiB&lt;/td&gt;
&lt;td&gt;7.8 MiB&lt;/td&gt;
&lt;td&gt;82%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024&lt;/td&gt;
&lt;td&gt;259&lt;/td&gt;
&lt;td&gt;34.2 MiB&lt;/td&gt;
&lt;td&gt;8.0 MiB&lt;/td&gt;
&lt;td&gt;77%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;255&lt;/td&gt;
&lt;td&gt;31.2 MiB&lt;/td&gt;
&lt;td&gt;6.8 MiB&lt;/td&gt;
&lt;td&gt;78%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;6.8 MiB&lt;/td&gt;
&lt;td&gt;1.8 MiB&lt;/td&gt;
&lt;td&gt;74%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2704&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~274 MiB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~66 MiB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~76%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;De PNG/JPEG qualité 90 à AVIF qualité 50 : entre 4 et 5 fois moins lourd.&lt;/p&gt;
&lt;p&gt;Le plus satisfaisant, c&amp;rsquo;est que je ne suis pas capable de détecter visuellement de perte de qualité. Les screenshots de terminal et mes photos passent très bien en AVIF 50.&lt;/p&gt;
&lt;h2 id="pré-compression-des-documents-html"&gt;Pré-compression des documents HTML
&lt;/h2&gt;&lt;p&gt;Après la conversion AVIF, &lt;a class="link" href="https://bsky.app/profile/slashgear.dev/post/3metqwv5aas2t" target="_blank" rel="noopener"
&gt;Antoine Caron (@slashgear.dev)&lt;/a&gt; m&amp;rsquo;a fait remarquer un truc :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Alors c&amp;rsquo;est pas mal déjà ! Je vois aussi que tes documents HTML ne sont pas compressés. Si ton blog est purement static, hésite pas à précompresser à balle et dire à ton server de servir les versions précompressées.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Effectivement, j&amp;rsquo;avais déjà &lt;code&gt;gzip on;&lt;/code&gt; dans ma config nginx, mais c&amp;rsquo;est de la compression &lt;strong&gt;à la volée&lt;/strong&gt;. Nginx utilise par défaut un niveau de compression modéré (niveau 6 sur 9) pour ne pas consommer trop de CPU.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;blog.zwindler.fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="s"&gt;/usr/share/nginx/html/blog.zwindler.fr/public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;gzip&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or, mon blog est &lt;strong&gt;100% statique&lt;/strong&gt;. Les fichiers ne changent qu&amp;rsquo;au rebuild. Ça veut dire qu&amp;rsquo;on peut les compresser une seule fois, avec le niveau maximum, et demander à nginx de servir directement les fichiers pré-compressés. Zéro CPU à chaque requête, mais surtout un meilleur ratio au final, car on peut compresser plus fort.&lt;/p&gt;
&lt;h3 id="côté-build--blog_refreshsh"&gt;Côté build : &lt;code&gt;blog_refresh.sh&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;J&amp;rsquo;ai ajouté les commandes de pré-compression après le &lt;code&gt;hugo --minify&lt;/code&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Pre-compress static files (gzip + brotli) for nginx gzip_static/brotli_static&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Zopfli: compatible gzip mais ~3-8% plus petit que gzip -9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; -v zopfli &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; find public -type f &lt;span class="se"&gt;\(&lt;/span&gt; -name &lt;span class="s2"&gt;&amp;#34;*.html&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.css&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.js&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.xml&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.json&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.svg&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.txt&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -exec zopfli --i1023 &lt;span class="o"&gt;{}&lt;/span&gt; +
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; find public -type f &lt;span class="se"&gt;\(&lt;/span&gt; -name &lt;span class="s2"&gt;&amp;#34;*.html&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.css&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.js&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.xml&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.json&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.svg&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.txt&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -exec gzip -k -f -9 &lt;span class="o"&gt;{}&lt;/span&gt; +
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Brotli pre-compression (better ratio than gzip, ~15-25% smaller)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; -v brotli &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; find public -type f &lt;span class="se"&gt;\(&lt;/span&gt; -name &lt;span class="s2"&gt;&amp;#34;*.html&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.css&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.js&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.xml&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.json&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.svg&amp;#34;&lt;/span&gt; -o -name &lt;span class="s2"&gt;&amp;#34;*.txt&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -exec brotli -k -f -q &lt;span class="m"&gt;11&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; +
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour la compression gzip, Zigazou m&amp;rsquo;a conseillé d&amp;rsquo;utiliser &lt;a class="link" href="https://github.com/google/zopfli" target="_blank" rel="noopener"
&gt;Zopfli&lt;/a&gt; (&lt;code&gt;apt install zopfli&lt;/code&gt;) plutôt que &lt;code&gt;gzip -9&lt;/code&gt;. Zopfli produit des fichiers 100% compatibles gzip mais avec un meilleur ratio (~3-8% en moins). C&amp;rsquo;est plus lent, mais sur un blog statique où on compresse une seule fois au build, on s&amp;rsquo;en fiche.&lt;/p&gt;
&lt;p&gt;En pratique, le gain de Zopfli est surtout un bonus : la majorité des navigateurs modernes supportent Brotli et recevront les &lt;code&gt;.br&lt;/code&gt;, qui sont de toute façon plus petits. Le &lt;code&gt;.gz&lt;/code&gt; ne sert que de fallback.&lt;/p&gt;
&lt;p&gt;Chaque fichier &lt;code&gt;index.html&lt;/code&gt; se retrouve ainsi avec un &lt;code&gt;index.html.gz&lt;/code&gt; et un &lt;code&gt;index.html.br&lt;/code&gt; à côté de lui.&lt;/p&gt;
&lt;h3 id="côté-nginx"&gt;Côté nginx
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Serve pre-compressed files generated at build time
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;gzip_static&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;brotli_static&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# nécessite libnginx-mod-http-brotli-static
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Fallback pour les contenus non pré-compressés
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;gzip&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;gzip_vary&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;gzip_min_length&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;gzip_types&lt;/span&gt; &lt;span class="s"&gt;text/plain&lt;/span&gt; &lt;span class="s"&gt;text/css&lt;/span&gt; &lt;span class="s"&gt;text/xml&lt;/span&gt; &lt;span class="s"&gt;text/javascript&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;application/javascript&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;application/xml&lt;/span&gt; &lt;span class="s"&gt;image/svg+xml&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour Brotli, sur &lt;strong&gt;Ubuntu 24.04+&lt;/strong&gt;, les paquets sont dans les dépôts officiels :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="le-gain-mesuré"&gt;Le gain mesuré
&lt;/h3&gt;&lt;p&gt;Un petit &lt;code&gt;curl&lt;/code&gt; pour comparer la page d&amp;rsquo;accueil :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Avec Brotli (ce que reçoivent les navigateurs)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -so /dev/null -w &lt;span class="s2"&gt;&amp;#34;%{size_download}&amp;#34;&lt;/span&gt; -H &lt;span class="s2"&gt;&amp;#34;Accept-Encoding: br, gzip&amp;#34;&lt;/span&gt; https://blog.zwindler.fr/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# =&amp;gt; 6 206 bytes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Sans compression&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -so /dev/null -w &lt;span class="s2"&gt;&amp;#34;%{size_download}&amp;#34;&lt;/span&gt; -H &lt;span class="s2"&gt;&amp;#34;Accept-Encoding: identity&amp;#34;&lt;/span&gt; https://blog.zwindler.fr/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# =&amp;gt; 32 886 bytes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;-81% sur le HTML&lt;/strong&gt;, de 33 Ko à 6 Ko transférés. Et on le vérifie dans Chrome DevTools : le header &lt;code&gt;Content-Encoding: br&lt;/code&gt; confirme que Brotli est bien servi.&lt;/p&gt;
&lt;p&gt;Et c&amp;rsquo;est pareil pour les autres fichiers textes statiques (CSS, JS).&lt;/p&gt;
&lt;h2 id="bilan"&gt;Bilan
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Optimisation&lt;/th&gt;
&lt;th&gt;Avant&lt;/th&gt;
&lt;th&gt;Après&lt;/th&gt;
&lt;th&gt;Gain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Images (AVIF)&lt;/td&gt;
&lt;td&gt;274 MiB&lt;/td&gt;
&lt;td&gt;66 MiB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-76%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML page d&amp;rsquo;accueil (Brotli)&lt;/td&gt;
&lt;td&gt;33 Ko transférés&lt;/td&gt;
&lt;td&gt;6 Ko transférés&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-81%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Le tout sans aucune dégradation visible de la qualité des images, et zéro impact CPU côté serveur pour la compression (puisqu&amp;rsquo;elle est faite au build).&lt;/p&gt;
&lt;p&gt;Et des webperfs qui ont bien progressé, même en mobile :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2026/02/webperf.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="addendum"&gt;Addendum
&lt;/h2&gt;&lt;p&gt;Un peu en vrac&amp;hellip;&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai du repasser sur du webp pour les images en frontmatter car les sites sociaux (bluesky / slack / linkedin) ne supportent pas AVIF :-/.&lt;/p&gt;
&lt;p&gt;On m&amp;rsquo;a conseillé &lt;a class="link" href="https://github.com/google/zopfli" target="_blank" rel="noopener"
&gt;zopfli&lt;/a&gt; en remplacement de gzip.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pourquoi ne pas utiliser zopfli &amp;ndash;i1023 en lieu et place de gzip -9 ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sauf que :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la très grande majorité supportent le brotli donc le gain sera marginal&lt;/li&gt;
&lt;li&gt;Sur ma mini VM, le zopfli n&amp;rsquo;aboutissait jamais (bug ou trop intensif en CPU)&lt;/li&gt;
&lt;li&gt;le projet n&amp;rsquo;est plus maintenu et qu&amp;rsquo;il a été archivé en octobre dernier.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sinon, il y a &lt;a class="link" href="https://github.com/ebiggers/libdeflate" target="_blank" rel="noopener"
&gt;libdeflate-gzip&lt;/a&gt;, sur le papier aussi bon que zopfli (pas testé) et semble encore maintenu.&lt;/p&gt;
&lt;p&gt;On m&amp;rsquo;a aussi indiqué qu&amp;rsquo;il y a un paramètre nginx pour hériter les headers&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header_inherit" target="_blank" rel="noopener"
&gt;https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header_inherit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>