Éliminer le double chargement d’image
Une seule image, la bonne taille, chargée une fois : srcset plutôt que background-image et img cumulés.

2025
Refonte partielle et optimisation continue du thème Shopify · Thème Shopify optimisé (image, vidéo, chargement)
Sessei avait un thème Shopify existant, mais pas pensé pour la vitesse : images dupliquées entre background-image et balise img, lecteurs vidéo tiers (YouTube, Vimeo) lourds et peu fiables sur Safari, chargement qui n’ordonnait rien par priorité.
Plutôt qu’une réécriture complète, j’ai refait 50 à 60 % du thème dans un format minimaliste, par petites itérations depuis plus d’un an : hero en srcset avec la bonne image au bon moment, galerie produit qui charge la première photo en priorité et le reste en différé, vidéos en balise native HTML5 avec Intersection Observer plutôt qu’un player YouTube embarqué, CSS et polices ordonnées selon ce qui bloque le rendu et ce qui peut attendre.
Résultat : LCP à 908 ms, INP P75 à 56 ms.
Une seule image, la bonne taille, chargée une fois : srcset plutôt que background-image et img cumulés.
Packshot immédiat, galerie complétée en différé.
Vidéo native HTML5, lue seulement à l’entrée dans l’écran.
CSS critique inline, polices en swap, scripts différés.
Sous le capot
Trois règles appliquées partout dans le thème : la bonne ressource au bon moment (eager seulement pour ce qui est dans le viewport), le navigateur qui choisit (srcset, HLS/MP4, jamais un fichier unique « au cas où »), et le natif d’abord (img, video, Intersection Observer plutôt qu’une librairie de plus).
Performance
Le hero ne charge plus la même image deux fois, et sert la bonne taille au bon écran.
Performance
La première photo produit charge en priorité, le reste de la galerie suit en différé.
Vidéo
Fini YouTube et Vimeo embarqués : une section vidéo native, lue seulement quand elle est visible.
Mobile
Un téléphone ne télécharge plus les visuels pensés pour desktop.
CSS
CSS critique inline, polices en swap, scripts différés : le navigateur sait quoi faire en premier.
01 / 05
Problème
L’image de hero, souvent l’élément LCP, était chargée deux fois (en background-image et en img), et servie en une seule taille quel que soit l’écran.
Approche
Passage au filtre Liquid image_tag avec un vrai srcset : paliers jusqu’à 3840 px sur desktop, jusqu’à 1780 px sur mobile, sans télécharger la version 4K sur un téléphone. L’image visible passe en loading="eager" et fetchpriority="high", uniquement elle. Si une image mobile dédiée existe, la version desktop passe en lazy sur petit écran, et inversement. Le navigateur choisit la bonne largeur, plutôt qu’un JPEG unique trop lourd envoyé à tout le monde.
Hero : une image, la bonne, tout de suite
02 / 05
Problème
Faire attendre le visiteur que toute la galerie produit soit chargée avant de voir la première photo.
Approche
La première image de la galerie charge immédiatement en priorité haute ; les suivantes passent en lazy et en priorité basse, avec un srcset jusqu’à 3600 px. Les vidéos produit passent en HTML5 avec preload="metadata", pour charger la miniature et la durée plutôt que le fichier entier. Le visiteur voit le packshot tout de suite, le carrousel se complète ensuite.
Fiche produit : la première photo d’abord
03 / 05
Problème
Les iframes YouTube ou Vimeo alourdissent la page (scripts, cookies, tracking) et posent régulièrement des soucis sur Safari et iOS.
Approche
Une section vidéo 16/9 construite sur la balise vidéo native de Shopify (HLS et MP4, le navigateur choisit), sans player tiers. Lecture en muted, playsinline et loop pour permettre l’autoplay sur Safari et iPhone, preload="metadata" pour ne pas télécharger le fichier complet au chargement de la page. Un Intersection Observer déclenche la lecture à l’entrée dans l’écran et la coupe à la sortie : la bande passante n’est utilisée que quand la vidéo est vraiment regardée.
Vidéo native plutôt que lecteur tiers
04 / 05
Problème
Sur une grille à trois colonnes, tout le contenu desktop n’a pas besoin d’exister sur mobile, ni au même poids.
Approche
Images desktop et mobile distinctes, aux tailles adaptées, plutôt qu’une seule image redimensionnée en CSS. Les colonnes masquées sur mobile ne sont pas affichées, tout ce qui est hors du premier écran passe en lazy, et les attributs width et height limitent le décalage de mise en page (CLS).
Mobile : ne pas envoyer ce qu’on ne montre pas
05 / 05
Problème
Un budget de chargement limité, dépensé sans ordre de priorité entre ce qui doit s’afficher immédiatement et ce qui peut attendre.
Approche
En priorité : preconnect vers les CDN Shopify, preload de theme.css, theme.js et lazysizes, CSS critique inline pour le header et la première section visible, polices en WOFF2 avec font-display: swap pour que le texte s’affiche tout de suite. En différé : scripts en defer (Alpine, thème, Swiper), lazysizes en async, CSS non critique chargé via le pattern media="print" puis basculé en all. Côté code, Tailwind préfixé plutôt que des feuilles monolithiques empilées à chaque section, et Alpine.js pour le menu plutôt qu’une couche jQuery de plus.
Priorités CSS, JS et polices
Décisions
Non, 50 à 60 % environ, dans un format minimaliste, par petites itérations plutôt qu’une réécriture complète d’un coup.
Projets

2026
Boutique Shopify Plus pour Näak, marque de nutrition et d’hydratation ultra-trail partenaire de l’UTMB® World Series. Refonte produit, abonnements et déploiement multi-marchés.

2026
Thème Shopify OS 2.0 écrit from scratch pour Slicy, protections et stickers vélo sur-mesure : configurateur de matching et personnalisation SVG en direct.

2026
Migration WooCommerce vers Shopify pour GoodBro, animalerie en ligne : 760 produits, 37 130 commandes, 1 177 abonnements, zéro email client.
Suite
Pas besoin de tout réécrire : la bonne ressource au bon moment change déjà beaucoup.