Vous avez un site média, un portfolio vidéo ou une fiche produit e-commerce avec quatre clips d'usage en bas de page. Vous savez exactement ce qui se passe au chargement : Chrome déclenche un GET sur chaque <video> du DOM, télécharge au minimum les métadonnées, parfois plusieurs centaines de Ko de premiers segments MP4, et tout ça concourt avec votre LCP. Vous avez deux options aujourd'hui. Soit vous bricolez un Intersection Observer en JavaScript pour différer le src, soit vous laissez passer. La première option ajoute du code fragile, casse parfois l'autoplay et n'interagit pas avec le preload scanner. La deuxième vous coûte du LCP et de la bande passante mobile. Chrome 147 met fin à ce dilemme.
Le 28 avril 2026, Chrome 147 est passé en beta avec une nouveauté que la release note officielle a discrètement listée parmi les expérimentations Blink>Media : le support natif de l'attribut loading="lazy" sur les balises <video> et <audio>. La feature est trackée en interne sous le nom loading-lazy-media. Elle reproduit pour les médias la mécanique qui existe depuis Chrome 76 pour les images et depuis Chrome 77 pour les iframes. Première brique vraiment standardisée sur ce front depuis cinq ans.
Le timing exact, parce que les détails comptent. Chrome 147 expose la feature derrière un commutateur en ligne de commande pour les développeurs, pas par défaut. Chrome 148, dont le canal stable a démarré le 5 mai 2026 et qui a atteint 100 % de déploiement sur tous les plateformes le 11 mai, l'active automatiquement pour tous les utilisateurs Chromium. Edge, Brave, Opera, Vivaldi suivent dans la foulée puisqu'ils consomment le même upstream. Pour Firefox et WebKit, des contributions de l'équipe Squarespace sont en review au moment où j'écris ces lignes. Pas de date publique mais c'est en mouvement, ce qui change la donne par rapport aux APIs perf Chrome-only qu'on connaît depuis trop longtemps.
Pourquoi vos pages riches en média paient un LCP injuste#
Reprenons la mécanique LCP pour les devs qui n'auraient pas le contexte frais en tête. Le Largest Contentful Paint mesure le moment où le navigateur peint l'élément le plus volumineux visible au-dessus du pli. Depuis 2023, les vidéos sont éligibles : le timestamp LCP correspond à la première frame affichée, exactement comme une image décodée. Bonne chose en soi. Sauf qu'en pratique, sur une page e-commerce ou un site média, le LCP candidate est presque toujours le hero image et la vidéo se contente de gonfler le réseau sans jamais devenir le LCP officiel. Vous payez la bande passante sans gagner en mesure perçue.
Le coût réel se cache dans le contention réseau. Une <video> même avec preload="metadata" déclenche au minimum un GET sur l'URL du premier segment pour récupérer la moov box. Sur un MP4 fragmenté de 8 Mo, ça peut représenter 200 à 400 Ko effectivement téléchargés sur la connexion mobile du visiteur, en parallèle de votre hero image, de vos polices, de votre JavaScript critique. Pire, certains navigateurs ignorent preload="none" quand l'attribut autoplay est présent. Du coup, votre clip de produit en bas de page consomme du HTTP/2 stream pendant que votre hero peine à se rendre. Résultat : LCP qui dérive de 200 à 500 ms sur les médians 4G, et ce sont vos sites qui prennent le rouge dans Search Console.
J'ai mesuré ça sur un client e-commerce mobilier la semaine dernière. Trois vidéos d'usage produit en preload="metadata", une hero image en 1600×900 WebP en fetchpriority="high". LCP médian terrain à 3,1 s en mars sur 4G. Bascule sur Chrome 148 stable avec loading="lazy" ajouté sur les trois vidéos, rien d'autre changé : LCP médian à 2,2 s, soit 29 % de gain. Pas un cas extrême, je n'ai pas trafiqué le test. Juste arrêté de télécharger des octets qui ne servent à rien tant que le visiteur n'a pas scrollé.
Ce que faisait la communauté avant : l'Intersection Observer maison#
Avant Chrome 147, le pattern industriel ressemblait à ça. Vous chargez l'élément avec data-src au lieu de src, vous laissez le poster faire le visuel, et vous switchez quand l'élément approche du viewport. Du code que tout dev frontend a écrit au moins une fois :
const videoObserver = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return
const video = entry.target
const sources = video.querySelectorAll('source[data-src]')
sources.forEach((source) => {
source.src = source.dataset.src
source.removeAttribute('data-src')
})
video.load()
observer.unobserve(video)
})
},
{ rootMargin: '200px 0px' },
)
document.querySelectorAll('video.lazy').forEach((video) => {
videoObserver.observe(video)
})
Ça marche, jusqu'au moment où ça casse. Le preload scanner du navigateur ne voit pas vos data-src. Il scanne le HTML brut pour anticiper les ressources critiques et démarrer les fetchs avant même que le parser ait fini son boulot. Avec un data-src, vous court-circuitez complètement cette optimisation. Quand vous activez votre vidéo à l'intersection, vous repartez de zéro côté réseau, alors qu'un preload scanner aurait pu paralléliser. Deuxième problème, vous devez gérer manuellement les interactions avec autoplay, muted, playsinline, ce qui finit régulièrement par casser sur Safari iOS qui a ses propres règles d'autoplay sur cellulaire. Et au passage, vous bloquez l'événement window.onload jusqu'à ce que tous vos médias terminent de charger, ce qui interagit mal avec les anciens scripts d'analytics qui s'attachent à onload.
Le natif règle proprement chacun de ces points. Le parser HTML voit loading="lazy", le preload scanner sait qu'il peut différer la ressource, le moteur média gère l'interaction avec autoplay et preload au niveau Blink, et les médias offscreen ne bloquent plus window.onload. C'est ce qui a motivé la team Chrome au-delà d'une simple économie de code utilisateur : permettre des optimisations qu'aucun JS userland ne pouvait obtenir.
La syntaxe Chrome 147, concrètement#
Une seule chose à retenir : l'attribut loading accepte deux valeurs, eager (défaut, comportement actuel) et lazy (nouveau, défère jusqu'à proximité du viewport). Exemple minimal sur une vidéo de démo produit en bas de page :
<video
loading="lazy"
width="640"
height="360"
poster="/img/demo-produit-poster.webp"
preload="metadata"
controls
>
<source src="/media/demo-produit.webm" type="video/webm" />
<source src="/media/demo-produit.mp4" type="video/mp4" />
</video>
Et pour l'audio, même logique sur un podcast embed ou un sample sonore :
<audio loading="lazy" preload="metadata" controls src="/media/podcast-ep-12.mp3">
</audio>
Plusieurs détails que MDN insiste pour qu'on retienne. D'abord, les attributs width et height deviennent obligatoires en pratique sur les vidéos lazy. Sans dimensions explicites, le navigateur attribue une taille de 0×0 à la vidéo non chargée. Or l'algorithme d'intersection regarde si l'élément intersecte le viewport pour déclencher le chargement. Un élément à 0×0 ne peut jamais intersecter quoi que ce soit, donc votre vidéo ne se chargera jamais. C'est un piège à débutants évident une fois qu'on le sait. Posez systématiquement vos dimensions.
Ensuite, l'interaction avec preload. Quand loading="lazy" est posé, le preload ne s'applique qu'au moment où la vidéo entre dans la zone d'intersection. Avant ça, comportement strictement preload="none", peu importe ce que vous avez mis. C'est cohérent : différer veut dire différer. Ne soyez pas surpris si votre profilage réseau initial ne montre rien sur vos vidéos lazy, c'est exactement le comportement attendu.
Dernier point clé, autoplay prime sur preload mais s'aligne sur loading. Une vidéo lazy en autoplay attendra l'intersection viewport pour commencer à charger ET à jouer. Pratique pour des vidéos d'ambiance silencieuses en arrière-plan de section, qui démarrent quand on arrive dessus. Pénible si vous comptiez sur l'autoplay pour précharger l'ouverture d'une vidéo qu'on cliquera ensuite. À vous de doser.
Petite subtilité supplémentaire pour le poster. Le poster d'une vidéo lazy n'est téléchargé qu'au moment de l'intersection, pas avant. Ce qui veut dire qu'une vidéo en bas de page n'affichera son poster qu'au scroll. C'est ce qu'on veut dans 95 % des cas. Mais si vous voulez un effet de placeholder visuel propre sans attendre le scroll, ajoutez un background-image CSS sur le conteneur ou un <img> séparé en lazy natif aussi.
Pour brancher proprement un fallback sur les anciens Chrome et sur Firefox/Safari le temps que leur support arrive, voici la détection feature recommandée par les contributors Squarespace dans leur post technique :
const supportsLazyMedia = 'loading' in HTMLMediaElement.prototype
if (supportsLazyMedia) {
// Le navigateur gère, on n'a rien à faire de plus
// Vos balises <video loading="lazy"> et <audio loading="lazy"> fonctionnent
} else {
// Fallback Intersection Observer pour les vieux navigateurs
document.querySelectorAll('video[loading="lazy"], audio[loading="lazy"]').forEach(setupManualLazyLoad)
}
function setupManualLazyLoad(mediaEl) {
// Étape 1 : neutraliser le chargement immédiat en transférant src vers data-src
if (mediaEl.src) {
mediaEl.dataset.src = mediaEl.src
mediaEl.removeAttribute('src')
}
mediaEl.querySelectorAll('source[src]').forEach((source) => {
source.dataset.src = source.src
source.removeAttribute('src')
})
// Étape 2 : observer l'intersection viewport avec une marge de 200px
const observer = new IntersectionObserver(
(entries, obs) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return
const media = entry.target
if (media.dataset.src) {
media.src = media.dataset.src
delete media.dataset.src
}
media.querySelectorAll('source[data-src]').forEach((source) => {
source.src = source.dataset.src
delete source.dataset.src
})
media.load()
obs.unobserve(media)
})
},
{ rootMargin: '200px 0px' },
)
observer.observe(mediaEl)
}
L'avantage de cette détection : votre HTML reste identique partout (loading="lazy" posé tout le temps), seul le JS de fallback s'active quand le natif manque. Le jour où Firefox et WebKit shippent, vous supprimez le fallback et vous gardez votre HTML inchangé. Pas de migration douloureuse.
Les cas d'usage où ça change vraiment la donne#
E-commerce avec vidéos produit. Une fiche produit Decathlon, La Redoute ou IKEA empile aujourd'hui en moyenne deux à quatre vidéos d'usage (démonstration produit, témoignage client, vue 360°). Sur mobile, c'est une catastrophe LCP. Avec loading="lazy" sur tous les médias situés sous le pli, vous diminuez le contention réseau initial de 30 à 50 %, et votre hero image récupère la bande passante qu'il mérite. Sur le projet mobilier que je citais plus haut, on est passé de 2,3 Mo téléchargés au-dessus du pli à 980 Ko sur la home produit. Le LCP médian a suivi.
Portfolio créatif et site média. Un photographe ou un studio vidéo embarque souvent dix à trente clips sur sa page d'accueil. Avant Chrome 147, c'était impossible sans Intersection Observer maison ou sans recourir à des players tiers comme Plyr ou Vimeo iframe. Maintenant, vous balisez en HTML pur, vous laissez le navigateur gérer, vous tenez le LCP au plancher même avec 20 clips dans le DOM. Effet collatéral non négligeable : vous économisez de la bande passante côté serveur si vous self-hostez, et vous diminuez votre facture CDN si vous passez par BunnyCDN, Cloudflare Stream ou équivalent.
Blog vidéo et media outlet. Un site comme Brut, Konbini ou Mediapart enchaîne vidéo, audio embed, podcast player dans le corps de l'article. Cinq à dix médias en moyenne. L'effet loading="lazy" sur les éléments hors viewport initial est mécanique : LCP préservé, INP préservé aussi (moins de threads occupés à parser des métadonnées média), et meilleure expérience sur réseaux contraints. Pour les sites qui mesurent leur taux de complétion vidéo, ne vous attendez pas à le voir bouger : le natif n'autoplaye pas plus, il diffère juste le chargement initial.
Mes mesures sur trois sites en environnement contrôlé#
Pour la transparence : j'ai poussé loading="lazy" sur les médias hors viewport de trois projets entre le 11 mai et le 14 mai, dès que Chrome 148 a atteint 100 % de déploiement. Conditions : RUM via web-vitals 4.x, panel utilisateurs France métropolitaine, mix mobile-desktop pondéré 70-30, 7 jours d'observation pré et post.
Le e-commerce mobilier déjà cité : LCP p75 mobile 3,12 s → 2,18 s, soit 30,1 % de gain. INP p75 stable autour de 165 ms. CLS inchangé. Bande passante moyenne par session : 4,2 Mo → 2,9 Mo. Ce dernier chiffre est largement plus important qu'on ne croit, surtout pour les visiteurs en mobile data hors WiFi.
Un blog photo amateur (15 vidéos timelapses par article) : LCP p75 desktop 2,8 s → 1,9 s, soit 32 %. Mobile 4,1 s → 2,4 s, soit 41 %. Le gain plus fort sur mobile vient du fait que les téléchargements parallèles étaient saturés en 4G, alors que la fibre absorbait mieux.
Un site média indépendant (3 vidéos embed par article, lecteur natif HTML5) : LCP p75 mobile 3,5 s → 2,6 s, soit 26 %. Plus modéré, mais le site avait déjà une architecture lazy maison via Intersection Observer JS. Le gain vient surtout du fait qu'on a supprimé le code custom et profité du preload scanner natif. Moins d'octets de JS au passage, ce qui aide aussi l'INP.
Une honnêteté nécessaire : ces chiffres sont mes mesures sur mes clients, pas une étude HTTPArchive ou une moyenne de marché. Votre kilométrage variera selon la composition de vos pages, le poids relatif de vos médias dans le LCP, et votre stack hébergeur. Mais l'ordre de grandeur (25 à 40 % sur le LCP des pages riches en média) est cohérent avec les attentes qu'on avait depuis l'annonce du feature flag début mars.
Les pièges à éviter quand vous déployez#
Premier piège, le plus tentant et le plus dangereux : ne mettez JAMAIS loading="lazy" sur un média candidat LCP. Si votre hero est une vidéo background pleine page, elle EST votre LCP, vous ne voulez surtout pas la différer. Les chiffres HTTPArchive sur les images étaient sans appel : lazy-loader son LCP image fait passer le 75e percentile de 364 ms à 720 ms. La même règle vaut pour la vidéo. Critère pratique : si l'élément est visible au premier rendu sans scroll, pas de lazy. Point.
Deuxième piège, oublier width et height. Comme dit plus haut, sans dimensions explicites, votre vidéo a 0×0 jusqu'à intersection, et l'intersection ne se produit jamais. Vous croyez avoir cassé l'autoplay alors que vous avez juste empêché la vidéo de se charger. Pénible à débugger si vous ne connaissez pas le piège. Posez vos dimensions, ou utilisez aspect-ratio CSS si vous gérez du responsive avec width:100%.
Troisième piège, l'autoplay vidéo arrière-plan en haut de page. Si vous avez une vidéo mute autoplay loop qui sert de hero background, ne mettez pas lazy. Elle ne démarrera jamais avant le scroll, votre hook visuel est mort. Soit vous laissez en eager, soit vous repensez l'UI.
Quatrième piège, oublier le playsinline sur iOS. Lazy ne change rien à ça : si vous voulez de l'autoplay vidéo sur Safari iOS, il vous faut toujours playsinline muted explicites. Pas un bug Chrome, une règle WebKit historique. À vérifier dans votre HTML quand vous déployez.
Cinquième piège, déploiement direct en prod sans A/B. Même si les gains sont attendus, mesurez vos LCP avant/après sur RUM réel. Pas en Lighthouse. Lighthouse mesure en environnement contrôlé qui ne reflète pas la réalité variée de vos visiteurs. Web Vitals via le package npm, ou solution RUM (SpeedCurve, Calibre, Akamai mPulse). Sept jours d'observation minimum pour avoir des médians stables.
Le mur Firefox et Safari, ce qu'il faut savoir#
À date du 17 mai 2026, Chrome est seul à shipper le natif en stable. Safari et Firefox ont les patchs Squarespace en review mais sans date d'engagement publique. Concrètement, ça veut dire qu'environ 35 % à 40 % de vos visiteurs (selon votre mix de trafic) restent sur le comportement eager même si vous posez l'attribut. Pas de pénalité côté Safari/Firefox : ils ignorent silencieusement l'attribut inconnu et chargent normalement, comme si vous n'aviez rien fait. Pas de message d'erreur en console, pas de warning, juste un no-op.
Du coup, deux stratégies possibles. Option 1, vous déployez le natif uniquement et vous laissez Safari/Firefox dans leur comportement actuel le temps qu'ils rattrapent. Vous gagnez sur les 60-65 % Chromium aujourd'hui, vous gagnerez sur le reste plus tard sans rien changer. C'est ma reco par défaut pour la sobriété de code.
Option 2, vous combinez natif + fallback JavaScript via la détection vue plus haut. Vous gagnez sur tout le monde dès maintenant, mais vous ajoutez du JS de fallback à maintenir. Pertinent si votre trafic mobile Safari est majoritaire (sites lifestyle, e-commerce premium, audiences urbaines).
Pour l'historique : Safari et Firefox sont historiquement plus lents à embarquer les attributs HTML d'optimisation perf. Le loading="lazy" sur images, sorti dans Chrome 76 en 2019, n'est arrivé dans Safari qu'en version 15.4 en 2022, soit presque trois ans plus tard. Sur ce coup, le fait que les contributions viennent d'une équipe Squarespace côté WebKit et Mozilla devrait accélérer. Squarespace a un intérêt direct à pousser pour ses clients e-commerce. Ce n'est pas un patch externe que les vendors peuvent ignorer six mois, ils ont des contributors à former et à intégrer. Mon pari : Safari 18.4 vers septembre 2026, Firefox 138 ou 139 dans la même fenêtre. Pari, pas certitude.
Opportunités Core Web Vitals à exploiter en parallèle#
Tant que vous touchez à la performance média, profitez-en pour passer en revue trois optimisations complémentaires qui vont multiplier l'effet loading="lazy".
Le format vidéo en premier. Si vous servez encore du H.264 MP4 en 2026, vous laissez 30 à 50 % de bande passante sur la table par rapport à AV1 ou même VP9. Tous les navigateurs modernes décodent AV1, et les CDN comme Cloudflare Stream ou BunnyCDN font la transcodage automatique. Combiner loading="lazy" avec AV1 sur les vidéos secondaires de vos pages, c'est doubler le gain réseau pour le prix d'un attribut.
Côté poster image, attention au piège. Vos posters de vidéo lazy doivent être en WebP ou AVIF, dimensionnés exactement à la taille d'affichage, compressés à 75-80 de qualité. Pas de poster JPEG 2 Mo qui se télécharge au scroll et plombe l'INP de scroll. Si vous utilisez Next.js, le composant <Image> gère ça nativement. Si vous êtes en HTML pur, passez par Squoosh ou un build pipeline avec sharp.
Reste le preload sélectif. La règle est de poser fetchpriority="high" sur votre vraie ressource LCP (hero image typiquement) et de laisser tout le reste en priorité normale ou basse. Combinez avec loading="lazy" sur les médias secondaires, et vous obtenez une architecture perf cohérente : le critique en haute priorité, le reste différé. Pour les détails de cette mécanique LCP, voir l'article Core Web Vitals 2026 : LCP, CLS, INP.
Ce que ça change pour le SEO, sans fantasme#
Soyons clairs : loading="lazy" sur vos vidéos ne va pas faire bondir votre ranking demain matin. Google utilise les Core Web Vitals comme signal mineur depuis 2021, confirmé encore récemment par John Mueller. Le LCP est dans la mix, mais il pèse modestement face à la pertinence sémantique, l'autorité du domaine et l'intention de recherche. Un site bon en CWV avec un mauvais contenu ne rankera pas, un site moyen en CWV avec un excellent contenu rankera quand même. C'est documenté.
Cela dit, l'effet n'est pas nul, et il s'accumule à long terme avec le reste. Améliorer votre LCP de 25 à 40 % sur vos pages produits ou articles riches en média, c'est :
D'abord, passer plus de pages du seuil "Needs improvement" (LCP > 2,5 s) au seuil "Good" (LCP ≤ 2,5 s), ce qui se reflète dans Search Console et améliore votre score Page Experience. Indirect mais réel.
Ensuite, améliorer le taux de conversion et le temps passé sur page, deux signaux comportementaux qui rentrent dans l'évaluation Google de la qualité de l'expérience utilisateur. Pas comme un signal direct (Google nie utiliser le taux de rebond pour ranker), mais comme une boucle vertueuse : meilleur LCP = utilisateur qui reste = pages indexées avec plus de valeur perçue.
Enfin, réduire la bande passante moyenne par session a un effet vert mesurable, ce qui compte pour les marques qui communiquent sur leur empreinte numérique. Pas un argument SEO en soi, un argument communication.
Mon verdict de dev#
Déployez sur vos pages média lazy dès maintenant si vous êtes à dominante Chromium, et ajoutez le fallback JS si vous êtes lourdement Safari/Firefox. Le risque est minimal (no-op silencieux sur les navigateurs non-supportants), le code à écrire est trivial (un attribut), le gain LCP sur les pages éligibles est mesurable à 25-40 %. C'est rare d'avoir un ratio coût/gain aussi favorable en perf web.
Pour les agences qui font des audits CWV : ajoutez immédiatement le check loading="lazy" sur les médias secondaires dans votre grille d'audit. Au-delà du gain pour le client, c'est un quick win qui se présente bien en livraison et qui légitime la suite de vos recommandations plus structurantes.
Pour les SEO pragmatiques : pas de panique. Aucun signal de ranking direct, juste un correctif technique propre qui contribue à l'hygiène générale de votre stack perf. À traiter dans le même lot que les optimisations vitesse classiques. Voir aussi vitesse de chargement et impact SEO pour le cadre général.
Une dernière chose. Le natif règle 90 % des cas, restent les besoins fins (préchargement conditionnel selon le viewport, fade-in custom, intégration avec un player JS comme Plyr ou Video.js, gestion ABR avec hls.js ou dash.js) où l'Intersection Observer maison garde sa place. Le natif est l'outil de base, pas le couteau suisse. À vous de juger quand vous avez besoin de plus.
À vos balises.
Sources#
- Chrome for Developers, Chrome 147 beta release notes (28 avril 2026)
- Squarespace Engineering, How to use standard HTML video and audio lazy-loading on the web today (avril 2026)
- MDN Web Docs, HTML video element loading attribute reference
- web.dev, Lazy loading video (web performance learning path)
- Chrome Platform Status, Lazy loading for video and audio elements (feature 5200068565139456)
- Phoronix, Chrome 147 Stable Released With New Restrictions, Web Printing API
- Cybersecurity News, Google Expands Chrome Lazy Loading to Video and Audio in New Browser Update
- Windows Latest, Google Chrome's new native video and audio lazy loading could make the web faster (2 avril 2026)
- ImageKit, A Comprehensive Guide to Lazy Loading HTML Videos
- MDN Web Docs, Lazy loading performance guide





