Lazy loading des images avec Claude Code: guide fiable pour débuter
Implémentez le lazy loading d’images avec Claude Code sans dégrader LCP, CLS, SEO ni UX.
Le lazy loading des images ne veut pas dire ajouter loading="lazy" partout. Si Claude Code retarde aussi l’image hero, le Largest Contentful Paint, c’est-à-dire le moment où le contenu principal devient visible, peut se dégrader. Si toutes les miniatures de produit, de galerie et d’articles liés chargent dès le départ, les lecteurs mobiles paient un coût réseau inutile.
Cette version fournit un modèle sûr pour débuter: lazy loading natif, image hero ou LCP en eager, decoding, fetchpriority, dimensions pour éviter le CLS, srcset et sizes, IntersectionObserver pour les cas avancés, placeholders, pièges SEO/UX, mesure et prompts Claude Code plus sûrs. Les points techniques ont été vérifiés avec la référence MDN de l’élément img, Intersection Observer API, l’article web.dev sur lelazy loading natif, Core Web Vitals et la documentation Chrome surLCP request discovery.
Pour compléter le sujet, lisez aussil’optimisation d’images, le skeleton loading etl’optimisation des performances.
La règle à retenir
Ne lazy-loadez pas ce que l’utilisateur voit immédiatement. Les images sous le premier écran peuvent utiliser le lazy loading natif. Toutes les images doivent garder un espace stable grâce àwidth etheight, ou à unaspect-ratio équivalent.
| Emplacement | loading | fetchpriority | decoding | Garde-fou |
|---|---|---|---|---|
| Hero ou candidate LCP | eager ou absent | high si pertinent | sync ou async | Découvrable dans le HTML initial |
| Diagramme au milieu d’un article | lazy | auto | async | Dimensions conservées |
| Grille produit après le premier écran | lazy | auto | async | srcset et sizes |
| Carousel ou scroll infini | Selon le cas | auto | async | IntersectionObserver si nécessaire |
L’erreur fréquente consiste à dire: “l’image est lourde, donc elle doit être lazy”. La vraie question est: “cette image est-elle nécessaire au premier rendu utile ?” Les recommandations Chrome pour LCP insistent sur trois points: l’image LCP doit être trouvée tôt, priorisée correctement et ne pas être marquéeloading=lazy.
HTML prêt à copier
La première image est la hero, donc elle utilise eager et une priorité élevée. La seconde est plus bas dans l’article ou dans une liste, donc elle utilise le lazy loading natif et un décodage asynchrone.
<img
class="hero-image"
src="/images/hero/product-dashboard-1200.webp"
srcset="
/images/hero/product-dashboard-640.webp 640w,
/images/hero/product-dashboard-1200.webp 1200w
"
sizes="100vw"
alt="Première vue d’un tableau de bord produit"
width="1200"
height="675"
loading="eager"
fetchpriority="high"
decoding="sync"
/>
<img
class="article-image"
src="/images/articles/setup-step-800.webp"
srcset="
/images/articles/setup-step-400.webp 400w,
/images/articles/setup-step-800.webp 800w
"
sizes="(max-width: 720px) 100vw, 720px"
alt="Capture d’écran d’une étape de configuration"
width="800"
height="450"
loading="lazy"
decoding="async"
/>
decoding="async" est un indice donné au navigateur. Il peut décoder l’image sans bloquer aussi fortement les autres tâches de rendu. C’est un bon défaut pour les images de contenu et les miniatures. Pour une hero, mesurezsync etasync avant de figer la règle.
Éviter le CLS avec CSS
CLS signifie Cumulative Layout Shift. En langage simple, c’est le déplacement de la page pendant que l’utilisateur lit ou clique. Une image sans hauteur réservée pousse le texte, la publicité, le formulaire newsletter ou le CTA. C’est un problème de conversion autant qu’un problème de performance.
.image-frame {
aspect-ratio: 16 / 9;
background: #f3f4f6;
overflow: hidden;
}
.image-frame > img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
@media (prefers-reduced-motion: no-preference) {
.image-frame > img {
transition: opacity 180ms ease-out;
}
}
Si votre CMS connaît les dimensions originales, stockez-les et passez-les au template. Si l’image vient d’une source externe inconnue, réservez au moins un conteneur stable avecaspect-ratio, puis ajustez l’image avecobject-fit.
Un composant React simple
Quand Claude Code modifie un projet React, mieux vaut placer la règle dans un composant. Les images prioritaires restent eager, les images de contenu deviennent lazy, et les dimensions sont obligatoires.
type SmartImageProps = {
src: string;
srcSet?: string;
sizes?: string;
alt: string;
width: number;
height: number;
priority?: boolean;
className?: string;
};
export function SmartImage({
src,
srcSet,
sizes,
alt,
width,
height,
priority = false,
className,
}: SmartImageProps) {
const loading = priority ? "eager" : "lazy";
const fetchPriority = priority ? "high" : "auto";
const decoding = priority ? "sync" : "async";
return (
<span
className={`image-frame ${className ?? ""}`}
style={{ aspectRatio: `${width} / ${height}` }}
>
<img
src={src}
srcSet={srcSet}
sizes={sizes}
alt={alt}
width={width}
height={height}
loading={loading}
fetchPriority={fetchPriority}
decoding={decoding}
/>
</span>
);
}
Le composant reste volontairement banal. Il n’enferme pas les images importantes derrière du JavaScript et peut s’adapter à Next.js, Astro ou un CMS.
Cas produits concrets
Premier cas: une grille ecommerce. Les premiers produits peuvent être visibles au chargement, donc ne passez pas toute la grille en lazy. Les recommandations, les avis, l’historique et la deuxième page visuelle sont de bons candidats. L’échec classique est d’ajouterfetchpriority="high" à chaque miniature: le navigateur ne sait plus ce qui est vraiment urgent.
Deuxième cas: un article ou tutoriel. L’image de couverture est souvent candidate LCP, donc elle doit rester eager. Les captures d’étapes, diagrammes sous les blocs de code et cartes d’articles liés peuvent être lazy. L’échec fréquent est de créer un placeholder flou en arrière-plan et de vider lealt de l’image réelle. Si l’image apporte du sens, le SEO et les lecteurs d’écran ont besoin de ce texte.
Troisième cas: un tableau de bord SaaS. Avatars, logos clients, miniatures de rapports et captures d’audit peuvent être nombreux. Lazy loader les lignes hors écran aide, mais il ne faut pas retarder le graphique principal, l’illustration d’onboarding ou l’image près du CTA. Pour suivre les clics CTA et les revenus, reliez ce travail àl’implémentation analytics.
Quatrième cas: une galerie ou un carousel horizontal. Le lazy natif suffit souvent, mais IntersectionObserver devient utile pour les conteneurs à scroll interne, les slides cachées ou une distance de préchargement précise.
Quand utiliser IntersectionObserver
Commencez par le lazy natif. Passez à IntersectionObserver quand vous voulez charger 300px avant l’apparition, remplacerdata-src, retirer une classe de placeholder ou observer un conteneur spécifique.
<img
class="js-lazy-image"
src="/images/placeholders/report-thumb.svg"
data-src="/images/reports/report-2026.webp"
data-srcset="/images/reports/report-2026.webp 1x"
alt="Miniature du rapport mensuel"
width="640"
height="360"
/>
const lazyImages = document.querySelectorAll("img[data-src]");
function loadImage(img) {
img.src = img.dataset.src;
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
img.removeAttribute("data-src");
img.removeAttribute("data-srcset");
}
if ("IntersectionObserver" in window) {
const observer = new IntersectionObserver((entries, currentObserver) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
loadImage(entry.target);
currentObserver.unobserve(entry.target);
});
}, {
rootMargin: "300px 0px",
threshold: 0.01,
});
lazyImages.forEach((image) => observer.observe(image));
} else {
lazyImages.forEach(loadImage);
}
Gardez les dimensions même dans cette approche. Une image endata-src peut ne jamais charger si JavaScript échoue. N’utilisez pas cette méthode pour la hero, l’image principale produit ou toute image essentielle au SEO.
Mesurer avant et après
Core Web Vitals se concentre sur LCP, INP et CLS. Les seuils courants sont LCP à 2,5 secondes ou moins, INP à 200 ms ou moins, et CLS à 0,1 ou moins. Pour les images lazy, LCP et CLS sont les plus sensibles.
npm install web-vitals
import { onCLS, onINP, onLCP } from "web-vitals";
onLCP((metric) => {
const lastEntry = metric.entries.at(-1);
console.log("LCP", metric.value, lastEntry?.element);
});
onCLS((metric) => {
console.log("CLS", metric.value, metric.entries);
});
onINP((metric) => {
console.log("INP", metric.value, metric.entries);
});
Dans Chrome DevTools, vérifiez si l’élément LCP est la hero attendue, si la requête image est découverte tôt depuis le HTML et si une image provoque un layout shift. Après publication, comparez PageSpeed Insights, Search Console et vos analytics.
Prompt Claude Code plus sûr
Claude Code sait faire des remplacements larges. Donnez-lui le périmètre, les règles et la validation avant les fichiers.
{
"goal": "Ajouter un lazy loading sûr aux images",
"scope": [
"Limiter aux images de corps d’article et listes produit",
"Ne pas lazy-loader les images de premier écran ou candidates LCP"
],
"rules": [
"Conserver alt, width et height sur chaque img",
"Utiliser loading=\"lazy\" et decoding=\"async\" sous le fold",
"Utiliser loading=\"eager\" ou omettre loading pour la hero",
"Utiliser fetchpriority=\"high\" sur une seule candidate LCP maximum"
],
"verification": [
"Vérifier MDX et code fences",
"Contrôler LCP et CLS dans DevTools",
"Tester sur mobile que image, texte et CTA ne se chevauchent pas"
]
}
Demandez aussi à Claude Code de lister les images qu’il n’a pas passées en lazy et pourquoi. C’est souvent la partie la plus utile de la revue.
Liste des erreurs
- La hero, l’image principale produit ou l’image du CTA haut est lazy.
widthetheightont disparu.- Toutes les images ont reçu
fetchpriority="high". - Les variantes
srcsetn’ont pas le même ratio sans art direction. - Une image de fond CSS est traitée comme un
img. - Un diagramme utile a un
altvide. - Une image importante dépend uniquement de JavaScript.
- Le placeholder attire plus l’œil que le contenu réel.
CTA et note de vérification
Le lazy loading ne sert pas seulement à améliorer un score. Il influence la profondeur de lecture, la visibilité du CTA, la navigation produit et la première action dans une application. Pour un usage individuel, commencez par lafiche Claude Code gratuite. Pour des prompts et modèles réutilisables, consultez lapage produits. Pour une équipe qui veut relier performance, SEO, analytics et monétisation, utilisezla formation et consultation Claude Code.
Pour cette mise à jour, j’ai revérifié les sources officielles ci-dessus et reconstruit les exemples autour d’une règle pratique: décider d’abord quelles images ne doivent pas être lazy. Dans le flux de Masa, le modèle stable a été hero eager, captures plus basses en lazy, dimensions partout,srcset mobile et prompt Claude Code avec échecs possibles et mesures dès le départ.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Échelle de sécurité des permissions Claude Code
Passer du read-only aux éditions limitées, preuves et checks de déploiement sans perdre le contrôle.
Claude Code Small PR Proof Pack : rendre les petits changements reviewables
Un pack de preuve pour PR Claude Code : diff, vérifications, URL publique, CTA et rollback.
Gate de review avant commit avec Claude Code
Review avant commit avec Claude Code : diff, build, URL publique, liens Gumroad, CTA consultation, tests manquants et fichiers hors scope.