À retenir
- Le filtre
image_tagde Shopify applique automatiquementloading="lazy"aux images au-delà des trois premières sections - vous devez explicitement définirloading="eager"sur votre hero.- Ajoutez
fetchpriority="high"à la balise<img>de votre hero pour la placer en tête de la file d’attente de téléchargement du navigateur.- Pour les hero utilisant
background-imageen CSS, ajoutez une balise<link rel="preload">dans le<head>detheme.liquid. L’URL doit correspondre exactement, sinon le navigateur téléchargera l’image deux fois.- La correction se fait dans
sections/image-banner.liquid(ouslideshow.liquid/ la section de votre hero), et non danstheme.liquidlui-même - à l’exception du preload.- Pas développeur ? La méthode la plus simple et la plus sûre pour effectuer cette correction est d’utiliser Fudge. Décrivez le changement en langage naturel et il modifiera les fichiers de la section pour vous - pas de code Liquid, pas de duplication de thème, aucun risque de tout casser.
Si un audit Lighthouse ou PageSpeed Insights vient de vous signaler que votre image hero est chargée en lazy-loading - ou que l’élément LCP a été préchargé trop tard - vous êtes au bon endroit. Ce guide détaille les modifications Liquid exactes à apporter pour que votre hero se charge immédiatement, avec un fetchpriority et un preload là où c’est nécessaire.
Pourquoi vous pouvez nous faire confiance
Nous avons travaillé avec des centaines de marques Shopify sur les performances de leur boutique, et nous avons créé Fudge - un éditeur de boutique IA noté 4.8 sur le Shopify App Store. Les méthodes ci-dessous sont celles que nous appliquons nous-mêmes et que nous recommandons lors de nos audits.
Pourquoi votre image hero est en lazy-loading
Il y a plusieurs causes courantes :
1. Le comportement par défaut de Shopify. Lorsque vous affichez une image avec le filtre image_tag et que vous ne définissez pas l’attribut loading, Shopify applique loading="lazy" à n’importe quelle image située au-delà de la troisième section du template1. Si votre section hero se trouve en quatrième position de la page (à cause d’une barre d’annonce, d’une promo sticky ou d’un carrousel d’apps la précédant), elle sera soumise au lazy-loading par défaut.
2. Le thème impose un code en dur loading="lazy". Certains anciens thèmes attribuent aveuglément cette valeur à chaque image, sans que le hero n’y échappe.
3. Le hero est une background-image CSS. Lorsque le hero est généré sous forme de background-image: url(...) plutôt que via une balise <img> classique, le navigateur ne le détecte pas lors de l’analyse initiale (parsing). Il n’y a donc aucun attribut loading applicable et le fetchpriority ne pourra rien y changer.
4. Une application ou une modification l’a supplantée. Certaines applications vont jusqu’à injecter des lignes de code dont le but est de remplacer la valeur eager par lazy sur toutes vos images visant à “améliorer les performances”. Ce qui s’avère être exactement l’inverse du but recherché pour un élément LCP.
Comment le diagnostiquer
Faites un clic droit sur l’image hero de votre storefront → Inspecter. Regardez la balise <img> dans le code HTML.
loading="lazy"est le problème. Remplacez-le parloading="eager".- L’absence d’attribut
fetchprioritysignifie que le navigateur la dépriorise par rapport aux autres ressources. Ajoutezfetchpriority="high". - S’il n’y a pas de balise
<img>du tout, cela signifie qu’il s’agit d’une background-image CSS - passez directement à la section sur le préchargement ci-dessous.
Lancez pagespeed.web.dev sur votre boutique. Sous l’onglet Diagnostics, l’entrée “Largest Contentful Paint element” (Élément LCP) indique quel élément est mesuré. S’il s’agit de votre hero et que la métrique “Load Delay” est élevée, c’est que l’image est récupérée trop tard.
Article connexe : Accélérer un Thème Shopify.
Corriger la balise <img> dans votre section hero
En général, le composant hero se situe dans l’un de ces fichiers de section - jamais au niveau de theme.liquid :
sections/image-banner.liquid(thèmes basés sur Dawn)sections/slideshow.liquidsections/hero.liquidousections/featured-hero.liquid(thèmes customs)
Étape 1. Dupliquez votre thème. Toujours.
Étape 2. Ouvrez le fichier de la section correspondante dans l’éditeur de code.
Étape 3. Trouvez la balise <img> ou l’appel au filtre image_tag. Pour les anciens thèmes, cela ressemble à ça :
<img
src="{{ section.settings.image | image_url: width: 2000 }}"
alt="{{ section.settings.image.alt }}"
width="2000"
height="1000"
loading="lazy"
/>
Étape 4. Remplacez loading="lazy" par loading="eager" et ajoutez fetchpriority="high" :
<img
src="{{ section.settings.image | image_url: width: 2000 }}"
alt="{{ section.settings.image.alt }}"
width="2000"
height="1000"
loading="eager"
fetchpriority="high"
/>
Si votre thème utilise le filtre image_tag plus moderne :
{{ section.settings.image
| image_url: width: 2000
| image_tag: loading: 'eager', fetchpriority: 'high', alt: section.settings.image.alt
}}
Étape 5. Sauvegardez et rechargez. Faites un clic droit sur votre hero, cliquez sur Inspecter, et confirmez que les nouveaux attributs sont bien en place.
Un pattern plus propre : section.index
Coder en dur loading="eager" fonctionne bel et bien, mais encore faut-il s’assurer que sa section ne bougera pas de place (soit un cas de figure où on dépose son fameux hero tout en bas dans l’Éditeur de thème). Et tout d’un coup, on n’est plus face à l’élément LCP alors qu’il est toujours chargé de manière eager. Le pattern le plus nomade recourt à section.index :
{%- liquid
assign loading = 'eager'
assign fetchpriority = 'auto'
if section.index == 1
assign fetchpriority = 'high'
elsif section.index > 2
assign loading = 'lazy'
endif
-%}
{{ section.settings.image
| image_url: width: 2000
| image_tag: loading: loading, fetchpriority: fetchpriority, alt: section.settings.image.alt
}}
En d’autres termes : si je suis placé en guise de première section de page, mon affichage hérite d’une priorité de rendu fixée à high. Si ma position se cantonne au top 3 des sections introduites de prime abord, charge-moi en mode eager. Si aucun de ces critères n’est retrouvé, opte pour le lazy load. C’est le pattern que Shopify recommande à sa communauté dès qu’il s’agit d’insérer une section en mesure de se retrouver en dehors (ou au sein) des frontières propres au LCP1.
Précharger un hero en background-image CSS
Si votre hero est affiché en tant que background-image: url(...) dans le CSS, le navigateur ignore totalement de quoi il est question jusqu’à l’heure où votre feuille de style passe à la loupe et télécharge les informations requises avant la phase d’application concrète des résultats. Auquel moment le compte-gouttes du processus LCP tournera encore en trame de fond.
Le correctif est un preload (un repère de prechargement) dans le module <head> du fichier theme.liquid. Ceci notifie le navigateur de lancer un processus anticipé du téléchargement de la photo concernée de façon expresse, et d’omettre la lecture préliminaire en CSS.
Étape 1. Accédez au sous-dossier de configuration sous l’intitulé layout/theme.liquid.
Étape 2. Localisez le cadre <head>, et insérez un paramètre conditionnel de preload dont l’actionnement ne se manifestera que s’il est question d’une consultation sur la page sur laquelle il opère (cela reste, d’ordinaire, sur la page d’accueil) :
{%- if template.name == 'index' -%}
{%- assign hero_section = sections['image-banner'] -%}
{%- if hero_section.settings.image -%}
<link
rel="preload"
as="image"
href="{{ hero_section.settings.image | image_url: width: 2000 }}"
fetchpriority="high"
>
{%- endif -%}
{%- endif -%}
L’URL dans votre balise de préchargement se doit de correspondre à celle que le navigateur solliciterait, au besoin - à l’extrême justesse. Le même paramètre de largeur
width, même mode pour la dimension ducrop, même type d’extension au sujet duformat. S’il se trouve qu’un désaccord se crée à un seul petit caractère près, le moteur d’interprétation des rendus retéléchargera l’ensemble tout neuf sans pouvoir rien exploiter en aval et en rajoutant ainsi une énième surcharge dont on se passerait sans soucis.
Étape 3. Si l’affichage de votre image change selon la surface d’ancrage (une découpe sur smartphone différente), insérez les lignes de code sous imagesrcset ou bien avec imagesizes si votre but reste de faire correspondre ces repères à sa bonne taille en guise d’adaptation par navigateur :
<link
rel="preload"
as="image"
imagesrcset="{{ hero_section.settings.image | image_url: width: 800 }} 800w,
{{ hero_section.settings.image | image_url: width: 1200 }} 1200w,
{{ hero_section.settings.image | image_url: width: 2000 }} 2000w"
imagesizes="100vw"
fetchpriority="high"
>
Étape 4. À défaut faire les choses mieux, pourquoi ne pas transposer ladite figure de configuration de style d’image CSS background-image vers les attributions pures d’affichage, encadrées de leur vraie balise <img> de départ à sa section native. Cette transposition offre, le temps de cette petite retouche de position, un vrai mode natif au regard de ses instructions HTTP issues de son éditeur mère (ici Shopify). De l’autre côté de la route, tous composants visuels à travers d’autres paramétrages en background de type CSS, et destinés à illustrer ce que l’on attend à titre d’élément formel encadré, deviennent ici carrément un anti-pattern2.
N’appliquez pas fetchpriority="high" sur toutes vos images
Le terme fetchpriority="high" est reconnu en soi sous une appellation désignant une caractéristique aux ressources restreintes. Qu’on décide d’encadrer de très fortes attentes un groupe composé d’une petite flotte de cinq portraits imagés afin d’instaurer une condition sur son temps d’exposition à son audience - un navigateur web optera sans compromis pour celle à traiter de prime abord au désavantage des dernières (car il lui incombait tout de même du point de vue informatique de réaliser des choix contraignants en matière d’affichage compensatoire sur l’écran des autres cibles, à cause de son absence globale de directives). Indiquez un ciblage limité à une seule image selon la page étudiée : ce sera ici cet élément LCP qui figurera au sein de la ligne choisie.
La méthode ci-présente rejoint sur ses principes de logistique le fonctionnement des requêtes visant l’anticipation lors d’un preload (les directives informatiques destinées aux actions preloading dont nul navigateur web d’ordinaire n’hérite lors de simples instructions routinières sans code approfondi). C’en est une par page. Accumuler un tas de phases chargées d’anticipation visuelle au milieu des compétitions visées à obtenir leurs lots d’interactions vis-à-vis d’un support sous bande passante se traduira toujours par le but qu’il aurait mieux valu contourner au tout départ : ce ne sera qu’un résultat final encore plus lent.
Vérifiez le correctif
1. Inspectez le HTML généré. Assurez-vous que l’affichage de notre repère d’inspection fait référence aux attributions attendues soit loading="eager" sous notre fetchpriority="high", situées correctement au niveau de ce trait particulier <img> du hero.
2. Ouvrez l’interface de ce célèbre outil sur Chrome DevTools → au sein de sa division Network (Réseau) → et assurez un mode réinitialisation des contenus afin d’annuler les cache de sa configuration (reload with cache disabled). Catégorisez ses classements de vue avec le tri Priority. Ce paramètre, visible autour de ce qui touche directement notre balise fixée à son champ hero, se montrera avec force attributions pointant vers des considérations aux priorités extrêmement percutantes (ce Highest de retour d’un de ses indicateurs de réussite d’objectifs) et localisé au sommet de ces colonnes.
3. Retestez depuis l’une de ces analyses proposées sur ce module d’amélioration qu’incarne un pagespeed.web.dev sous contrôle. Notre fameuse mention “Largest Contentful Paint element” dans notre diagnostic se rafraîchira pour désigner de suite le retard lié au délai réduit à recompiler sur nos informations techniques. Des chiffres LCP descendront souvent aux niveaux impressionnants à l’issue d’une baisse, comprise entre les paliers des 500 et 2000 ms dès lors que s’y trouvera rattaché ce lent réseau en téléphonie d’une offre sous forfaits mobiles.
4. Ayant pris un préchargement de mise, lancez son contrôle via sa branche Network en fouillant l’information pour sa recherche vis-à-vis de son adresse relative. Notre vue cible devra s’y nicher et exister d’elle seule (jamais reproduite par 2 ou au-delà d’interrogation de chargements redondants de suite sans justification de ses attributions respectueuses ! ). Tout ce qui affiche sa paire sur une entrée vous mettra simplement à l’appui que sa retransmission échoue sous sa correspondance sur fond d’adresses divergentes en preloading : veillez au grain de le supprimer à temps de ces mauvaises pratiques.
Vous n’avez pas envie de modifier le code Liquid ?
Tout le déroulé au fil de cet exposé part de la supposition que son exécution reste familièrement acquise sans tracas de mise en page manuelle de la modification et tout avec vos encadrements des marqueurs balises. Dans cet esprit de simplicité évidente à la moindre appréhension sur la chose abordée en profondeur sur le Liquid, ce module d’action à distance nommé Fudge exécutera toute sa fonction à travers l’intervention sur une écriture simple en base promptée de mise à jour. C’est à la hauteur d’une description simple du paramétrage comme suivant :
“Sur cette fameuse bannière d’ouverture à partir du hero sise d’accueil liée au fichier
theme.liquid, place-moi toutes tes dispositions avecloading=eageraccompagné de sa balise sousfetchpriority=highvisant l’affichage qui y figure de l’image. Est-ce positionné en sa caractéristique issue d’éléments décors orientés autour d’une écriture sur format dit en ressource vis-à-vis à du code en CSS derrière tout le design à titre unique sans images à ancrage basique ? Intègre en ce cas ton aide de code liée sur les mises au point à configurer de preload de la configuration au nom de tout l’apprêt au coeur des réglages templates et fixée sur ce trait index de l’accueil.”
Au moment attendu face aux changements de requêtes dictés que comprend cette formulation d’intentions exprimée, cet algorithme performant Fudge pondra précisément vos extraits corrigés et présentés pour s’admirer sur sa validation visuelle sur thème de magasin. Seulement par la suite validée en l’action d’une authentification consentie par vos touches interposées ! Zéro casse-tête aux démultiplications sans queue sur cet aperçu Liquid pour la gestion simplifiée (pas besoin de syntaxe à se farcir par l’oubli).
Les pièges courants
Le hero est dans un diaporama avec plusieurs slides. Seule la première slide est visible au premier affichage. Appliquez l’eager loading et fetchpriority="high" uniquement à l’image de la première slide - chargez le reste en lazy loading.
Le hero change selon le template. Un hero de page d’accueil et un hero de page de collection sont des sections différentes. Appliquez le correctif à chacune, et conditionnez vos preload hints avec if template.name == 'index', etc.
Votre image n’est pas servie en WebP. Le CDN de Shopify sert automatiquement le format WebP lorsque le navigateur le supporte - mais seulement si vous passez par image_url ou img_url. Un simple src="...assets/banner.jpg" brut n’affichera pas de WebP. Utilisez les filtres Liquid.
Une application écrase vos modifications. Si vous corrigez la section mais que l’outil Inspecter affiche toujours loading="lazy", c’est que le JavaScript d’une application modifie le DOM après le chargement de la page. Cherchez parmi vos applications installées des outils de “performance” ou d‘“optimisation d’image” - certaines d’entre elles réappliquent loading="lazy" à tout sans aucune distinction.
Article connexe : Lazy Loading des images sur Shopify.
Article connexe : Compresser les images sur Shopify.
Article connexe : Corriger les scripts bloquant le rendu sur Shopify.
Article connexe : Cumulative Layout Shift sur Shopify - un hero qui se charge tardivement sans espace réservé décale tout ce qui se trouve en dessous.
Quand s’attendre à une vraie baisse du LCP
Si votre image hero était en lazy-loading et volumineuse, attendez-vous à une amélioration du LCP de 1 à 3 secondes sur une 4G lente. Si elle était déjà en eager mais sans fetchpriority, attendez-vous à un gain de 200 à 800 ms. Si vous corrigez également une background-image CSS avec une balise preload, le gain se cumule.
Si vous apportez ces modifications et que PageSpeed indique toujours que le LCP est lent, le goulot d’étranglement s’est déplacé ailleurs - CSS ou JavaScript bloquant le rendu, temps de réponse du serveur, ou une image hero simplement trop lourde. Compressez d’abord l’image, puis examinez les scripts.
FAQ
Le filtre image_tag de Shopify applique loading="lazy" aux images situées après la troisième section du template. Si votre image hero est la 4ème section (ex. : après la barre d'annonces, la promo sticky, la section app), elle est chargée en lazy-loading. C'est un bon comportement par défaut pour les images non-LCP, mais préjudiciable pour l'image hero — définissez explicitement loading="eager".
Non. Utilisez loading="eager" uniquement pour l'élément LCP — généralement une seule image hero. Les autres images au-dessus de la ligne de flottaison (logo, icônes de navigation, bannières secondaires) sont suffisamment petites pour que le choix entre lazy-loading et eager loading n'affecte pas le LCP de manière significative. La règle est également de n'utiliser fetchpriority="high" que sur une seule image par page.
Non — au contraire. fetchpriority="high" est un signal relatif. Si plusieurs images sont marquées 'high', le navigateur dépriorise le véritable élément LCP pour compenser. Définissez-le sur exactement une image (l'élément LCP) par page. Il en va de même pour les balises preload — une seule par page.
Theme.liquid est l'emplacement conventionnel car le <link rel="preload"> doit se trouver dans <head> et theme.liquid englobe chaque page. Certaines sections prennent en charge un point d'injection {% layout 'theme' %}, mais la plupart non. Si vous ne pouvez pas modifier theme.liquid directement, Fudge peut effectuer la modification en toute sécurité sans toucher au code.
Trois façons : (1) Clic droit sur l'image hero → Inspecter → confirmez que loading="eager" et fetchpriority="high" sont sur la balise <img>, (2) Chrome DevTools → onglet Network → recharger → trier par Priority → l'image hero devrait être Highest, et (3) relancer PageSpeed Insights — le "Load Delay" du LCP devrait baisser et le score LCP global s'améliorer.
Footnotes
-
Recommandations officielles de Shopify sur le filtre
image_taget les valeurs par défaut desection.index: Announcing new Liquid features for better web performance. ↩ ↩2 -
Recommandation de Web.dev sur l’évitement de
background-imageCSS pour les éléments LCP : voir Optimizing images for performance on Shopify. ↩