Lighthouse CI : un historique de nos mesures à chaque déploiement
En 2024, nous avions fixé un éco-budget pour nos pages. Il est désormais vérifié à chaque mise en ligne par un serveur Lighthouse CI gratuit qui garde l'historique des mesures.
En juillet 2024, nous avons publié la définition de notre éco-budget : des pages de moins de 1 024 Ko, avec moins de 40 requêtes et moins de 600 éléments dans le DOM. L’article promettait d’expliquer plus tard « comment intégrer ces indicateurs dans votre processus d’intégration continue ». Voici cette explication, avec deux ans de retard et quelques corrections.
Ce que faisait notre première étape Lighthouse
En 2024, notre déploiement lançait déjà Lighthouse, l’outil d’audit de Google intégré à Chrome. L’étape répondait par oui ou par non : la page respecte le budget, ou elle ne le respecte pas. Nous y avions mis des seuils de temps de chargement, retirés dès le 16 mai 2024 parce qu’ils faisaient échouer des déploiements au hasard. La base de données des résultats était rangée dans le dépôt du site, à côté du code, et l’étape a fini par disparaître du workflow.
Un oui ou non ne dit rien de la pente. Une page qui passe de 150 à 290 Kio en six mois respecte toujours un budget de 500 Kio. Personne ne le remarque avant le jour où elle le dépasse, et ce jour-là, il faut retrouver lequel des cinquante derniers déploiements a commencé à l’alourdir.
Un serveur qui garde chaque mesure
Lighthouse CI (LHCI) est l’outil d’intégration continue publié par l’équipe Chrome. Il lance Lighthouse, vérifie des seuils, et peut envoyer les rapports à un serveur qui les conserve et les affiche en courbes, déploiement par déploiement.
Chez nous, chaque push déroule désormais quatre étapes :
- le site est construit et envoyé chez notre hébergeur, comme avant ;
- une fois le site en ligne, Lighthouse mesure six pages, trois fois chacune : l’accueil, les réalisations, les expertises, l’outil d’audit, la liste des articles et un article illustré ;
- les rapports partent sur le serveur LHCI ;
- le budget est vérifié, et s’il est dépassé, un message arrive dans notre canal Slack.
Un dépassement ne bloque pas la mise en ligne. Nous mesurons le site réel, avec la compression et les en-têtes de cache de l’hébergeur, ce qui oblige à mesurer après le déploiement : quand l’alerte tombe, la page est déjà en ligne. Bloquer le job à ce moment-là ne corrigerait rien.
Notre préproduction et la production envoient leurs rapports au même projet, chacune sur sa branche. Le serveur compare chaque page de préproduction à la même page en production, ce qui permet de voir une régression avant qu’elle ne parte chez les visiteurs.
Gratuit, avec une contrepartie
Un serveur d’historique a besoin d’un endroit où garder ses données dans la durée. Les offres gratuites ne le permettent pas toutes. Chez Render, que nous utilisons déjà, un service gratuit n’a pas de disque persistant, et la base Postgres gratuite expire au bout de 30 jours. Nous avons donc séparé les deux : le serveur tourne sur l’offre gratuite de Render, les données sont stockées dans une base Postgres gratuite chez Neon, permanente et limitée à 0,5 Go.
En contrepartie, Render endort le serveur après 15 minutes sans visite, et il met environ une minute à se réveiller. Notre workflow commence donc par l’appeler en boucle jusqu’à ce qu’il réponde. Une minute de plus sur un déploiement, c’est un prix que nous acceptons pour un serveur qui ne coûte rien et ne tourne pas quand personne ne s’en sert.
Le budget, version 1
| Ressource | Seuil | Page la plus lourde mesurée |
|---|---|---|
| Poids total | 500 Kio | 302 Kio (liste des articles) |
| Images | 300 Kio | 211 Kio (liste des articles) |
| Polices | 100 Kio | 81 Kio (accueil de la refonte) |
| Scripts | 100 Kio | 22 Kio |
| Requêtes | 40 | 28 |
| Requêtes vers des tiers | 5 | 4 |
Le budget de 2024 annonçait 1 024 Ko par page. En septembre 2026, notre page la plus lourde en transfère 302. Garder 1 024 aurait laissé une page tripler sans la moindre alerte, alors nous l’avons ramené à 500 Kio. Les seuils par type de ressource servent à attraper les erreurs courantes : une bannière oubliée en pleine résolution, une police ajoutée pour essayer, un script de suivi installé en passant. Le plafond de 40 requêtes vient de 2024 et reste large. Celui des requêtes vers d’autres domaines est serré exprès : nous voulons décider de chaque nouveau service externe, et non le découvrir dans un rapport.
Deux précisions sur les chiffres. Lighthouse compte en kibioctets de 1 024 octets, là où la pastille de poids en bas de nos pages compte en kilo-octets de 1 000, comme Chrome. Et Lighthouse simule un téléphone : il reçoit les images prévues pour un petit écran, plus légères que celles d’un ordinateur.
Ce qui n’y est pas encore
Les 600 éléments de DOM de 2024 ne figurent pas dans cette version. Le format budget.json ne sait exprimer que des poids, des nombres de requêtes et des temps, et Lighthouse CI refuse de mélanger un fichier de budget avec ses propres assertions. Nous avons préféré commencer simple. La mesure nous a d’ailleurs rappelés à l’ordre : l’accueil actuellement en production compte 763 éléments, au-dessus de l’objectif que nous affichions. Celui de la refonte, en préproduction, en compte 455.
Pas de temps de chargement non plus. Les machines de GitHub Actions sont partagées, et d’un passage à l’autre les temps varient assez pour faire échouer un seuil sans que le site ait changé. C’est ce qui était arrivé à nos premiers seuils en 2024. Les temps restent enregistrés dans l’historique, où une tendance sur vingt déploiements dit plus qu’une mesure isolée.
Sous le capot : le fichier de budget et les commandes
Le budget tient dans un fichier budget.json à la racine du dépôt. "path": "/*" applique les mêmes seuils à toutes les pages ; les tailles sont en kibioctets.
[
{
"path": "/*",
"resourceSizes": [
{ "resourceType": "total", "budget": 500 },
{ "resourceType": "image", "budget": 300 },
{ "resourceType": "font", "budget": 100 },
{ "resourceType": "script", "budget": 100 }
],
"resourceCounts": [
{ "resourceType": "total", "budget": 40 },
{ "resourceType": "third-party", "budget": 5 }
]
}
]Lighthouse a retiré les budgets de son propre moteur en version 12, en avril 2024. Lighthouse CI continue de lire ce fichier et le traduit en assertions sur l’audit resource-summary, qui recense les ressources de la page par type.
Dans GitHub Actions, les trois commandes tournent l’une après l’autre, dans cet ordre :
npx @lhci/cli collect # six pages, trois passages chacune
npx @lhci/cli upload # envoi au serveur, même si le budget est dépassé
npx @lhci/cli assert # vérification du budget, en mode avertissementL’envoi passe avant la vérification : une mesure qui dépasse le budget est justement celle qu’on veut retrouver dans l’historique.
Pour comparer la préproduction à la production, le serveur apparie les pages par adresse. Nous réécrivons donc staging.ouzom.fr en ouzom.fr au moment de l’envoi, grâce à l’option urlReplacementPatterns ; la branche du déploiement indique d’où vient la mesure.
Le premier comparatif
L’image en tête d’article est le premier comparatif que nous avons obtenu, sur un serveur de test pendant la mise au point : la page d’accueil de la préproduction face à celle de la production. Performance, accessibilité et bonnes pratiques ne bougent pas. Le SEO perd 31 points, et c’est voulu : notre préproduction publie un fichier robots.txt qui interdit l’indexation, pour que les moteurs de recherche ne la confondent pas avec le site public. Lighthouse le détecte et le sanctionne.
Le même écran annonce 410 millisecondes de plus pour l’affichage du plus grand élément de la page en préproduction. Nous n’en tirons rien pour l’instant : chaque page n’avait été mesurée qu’une fois, et c’est pour ne plus juger sur une mesure isolée que nous avons mis ce serveur en place.
Mesurer sans alourdir
Restait le poids des mesures elles-mêmes. Pour notre accueil, un rapport Lighthouse brut pèse 687 Kio, dont 420 Kio de captures d’écran encodées en texte. Nous les avons désactivées : le rapport descend à 265 Kio, et en moyenne à 62 Kio une fois stocké, parce que Postgres compresse les gros champs de texte. Les captures d’écran, elles, se compressent très mal.
Un déploiement complet, six pages mesurées trois fois, occupe ainsi environ 1,3 Mio. Les mesures de la préproduction sont effacées au bout de 90 jours, celles de la production sont conservées. À notre rythme de 2026, entre 12 et 26 déploiements par mois selon les périodes, les 0,5 Go de la base gratuite tiennent plusieurs années.
La suite
La prochaine version remplacera le fichier de budget par les assertions de Lighthouse CI, qui acceptent n’importe quel audit : la taille du DOM, le score d’accessibilité, puis des seuils par gabarit de page, puisque le blog porte plus d’images que les pages d’offre. Avant de les fixer, nous attendrons quelques semaines d’historique, pour régler ces seuils sur des courbes plutôt que sur une seule mesure.
← Tous les articles