Ressources
L'analyse du code
Repérer ce qui alourdit un site directement dans son code source
Sommaire
Avant même la mise en ligne
L'audit mesure le site tel qu'il est servi, mais beaucoup de ce qui l'alourdit se voit déjà dans le dépôt, une photo de quatre mégaoctets dans public/ ou une police en TTF par exemple. Le job .grammage-source lit donc le dépôt lui-même, sans navigateur ni aperçu, et signale ce qui pèsera sur les pages avant qu'elles partent en ligne, avec le fichier, la ligne et le correctif à appliquer.
grammage-source:
extends: .grammage-sourcegrammage source .
grammage source . --fail-on warningLe job ne bloque jamais le pipeline, parce qu'un constat sur le code dit ce qui risque de peser, pas ce qui pèse vraiment. --fail-on warning sert à l'équipe qui préfère bloquer quand même. L'analyse ne lit ni les dépendances, ni les sorties de construction, ni ce que le .gitignore écarte, ni les dossiers qui ne partent jamais en ligne, docs, scripts, tests et fixtures. Elle ne demande aucune licence, et l'API ne la fait pas, puisqu'elle n'a pas accès à votre code.
Ce que l'analyse signale
| Règle | Ce qu'elle signale | Le correctif |
|---|---|---|
source-image-heavy | une image matricielle de plus de 200 Ko | la compresser, la redimensionner à sa plus grande taille d'affichage et la servir en AVIF ou en WebP |
source-image-legacy | une photo en PNG ou en JPEG, à partir de 50 Ko | la convertir en WebP ou en AVIF, ou laisser le composant d'image du framework le faire |
source-image-oversized | une image de plus de 2 560 pixels de large | la ramener à 2 560 pixels au plus et proposer des largeurs plus petites par srcset |
source-font-format | une police en TTF, OTF ou WOFF | la convertir en WOFF2 et ne servir que ce format |
source-font-heavy | une police de plus de 100 Ko | la réduire aux caractères du site, par exemple avec pyftsubset |
source-autoplay | une vidéo ou un son en lecture automatique | retirer autoplay, afficher une image fixe et lancer la lecture au clic |
source-infinite-animation | une animation CSS qui tourne sans fin | donner un nombre fini d'itérations et respecter prefers-reduced-motion |
source-eager-island | un îlot Astro en client:load | passer en client:visible ou client:idle quand il n'est pas utile tout de suite |
source-framework-image | un <img> brut dans un projet Nuxt, Next.js ou Astro | passer par <NuxtImg>, next/image ou <Image /> d'astro:assets |
source-heavy-dependency | moment, lodash entier ou jquery en dépendance | Intl.DateTimeFormat, les fonctions importées une à une, ou le DOM natif |
source-server-compression | un Caddyfile sans encode, un nginx.conf sans gzip on | encode zstd gzip pour Caddy, gzip on; et brotli on; pour nginx |
source-server-cache | des fichiers statiques sans durée de cache | Cache-Control: public, max-age=31536000, immutable sur les fichiers à empreinte |
Chaque constat arrive dans le widget Code Quality de la demande de fusion, annoté sur la ligne du fichier concerné, donc la personne qui a ajouté l'image ou la dépendance le voit au moment où elle en parle avec son équipe, et pas trois mois plus tard.
Le code jamais exécuté, fichier par fichier
En production, le JavaScript inutilisé ne se voit que par paquet, _nuxt/B5pp_0lr.js par exemple, ce qui ne dit pas quel composant ou quelle dépendance corriger. Quand le job de CI a sous la main le build du projet avec ses source maps, Grammage rattache chaque octet jamais exécuté à son fichier d'origine, app/components/MapComponent.vue ou node_modules/gsap, et le rapport les classe du plus lourd au plus léger.
- Nuxt
- Vite
- Astro
- Next.js
Il faut pour ça deux choses. Le build produit des source maps sans les publier, ce que le mode hidden fait très bien, et le job de Grammage reçoit ce build en artefact, construit par le même pipeline que l'aperçu, pour que les fichiers correspondent vraiment à ce qui est servi.
export default defineNuxtConfig({
sourcemap: { client: 'hidden' },
});export default defineConfig({
build: { sourcemap: 'hidden' },
});export default defineConfig({
vite: { build: { sourcemap: 'hidden' } },
});module.exports = {
productionBrowserSourceMaps: true,
};grammage:
extends: .grammage
needs: [build, preview]| Framework | Réglage |
|---|---|
| Nuxt | sourcemap: { client: 'hidden' } dans nuxt.config.ts |
| Vite | build: { sourcemap: 'hidden' } dans vite.config.ts |
| Astro | vite: { build: { sourcemap: 'hidden' } } dans astro.config.mjs |
| Next.js | productionBrowserSourceMaps: true, puis ne pas déployer les .map |
Sans source maps, le rapport garde simplement le détail par paquet.
De la mesure au fichier du dépôt
En CI, le job d'audit lit aussi le dépôt cloné, et relie chaque fichier fautif mesuré sur la page à son fichier dans le dépôt, une image public/images/hero.png servie sous /_nuxt/hero.Bx1aB2cD.png ou par /_next/image par exemple. Le constat s'annote alors sur le bon fichier, et le brief grammage-agent.md donne à un agent de code ou à un collègue la liste des fichiers à toucher, le correctif propre au framework, le gain attendu et la commande qui vérifie que c'est fait.
Voyez ce que votre site pèse vraiment
Grammage réunit dans un seul outil l'audit dans un vrai navigateur, l'analyse du code dans la CI/CD et un résultat signé que chacun peut vérifier.
Essai gratuit, sans engagement.
Essayez gratuitement