LFW

Blog · Guides

Notre image principale disparaissait sur iPhone. Un bloqueur de publicités la cachait.

Pendant des semaines, l'image principale de trois de nos propres pages disparaissait une seconde et demie sur iPhone, au premier chargement seulement. Rien ne le reproduisait en laboratoire.

Un relevé de terrain de cinquante lignes l'a trouvé en trois chargements de page : un bloqueur de publicités masquait tout élément dont la classe commençait par ad-.

Le symptôme

Sur trois pages de ce site, le bloc principal, celui qui porte le titre et la photographie, n'était pas là quand la page se dessinait pour la première fois sur un iPhone. La section du dessous restait en haut de l'écran pendant environ une seconde et demie, puis le bloc apparaissait au-dessus. Rechargez la page et il était là instantanément. Ouvrez-la à neuf dans un onglet privé et il avait de nouveau disparu.

Cela n'arrivait que sur iPhone. Cela arrivait dans Safari et dans tous les autres navigateurs iOS, ce qui est logique puisqu'Apple les oblige tous à utiliser WebKit. Cela n'est jamais arrivé sur un ordinateur ni sur un téléphone Android.

Il arrive que même LFW ait des problèmes qui ne se rendent pas facilement. Celui-ci a pris des semaines, et nous avons livré plusieurs correctifs qui ne corrigeaient rien, parce que chacun était une théorie raisonnable sur le chargement des images et qu'aucun n'était la cause.

Les théories qui étaient fausses

Tout dans le symptôme désignait l'image. Une photographie principale qui arrive tard, une boîte qui ne lui est pas réservée, du contenu qui se décale quand le fichier atterrit. Nous avons donc réservé la boîte avec une largeur, une hauteur et un rapport d'aspect. Nous avons préchargé la photographie depuis l'en-tête du document. Nous avons rempli la boîte réservée d'un substitut flouté pour qu'elle ne soit jamais blanche. Chaque changement a rendu la page mesurablement meilleure et aucun n'a touché au bogue.

Nous avons tenté de le reproduire dans Chromium avec le réseau bridé à une connexion mobile lente. Le bloc principal était mis en page dès la première image. Nous avons installé un vrai WebKit sur un serveur et retenu chaque image et chaque police deux secondes et demie. Même résultat. En laboratoire, la page allait bien.

Mesurer là où cela se produit

À ce stade, l'attitude honnête était d'arrêter de théoriser. Nous avons ajouté à la page un petit script, temporaire et réservé aux téléphones, qui enregistrait où se trouvait réellement le bloc principal toutes les cent millisecondes pendant les cinq premières secondes, et renvoyait une ligne à notre serveur une fois terminé. Le tout faisait moins de cinquante lignes.

Afficher le code Masquer le code JavaScript, 17 lignes
// Sample the hero's position for five seconds, then send one beacon.
const hero = document.querySelector("header.pagehead");
const samples = [];
const t0 = performance.now();
const tick = setInterval(() => {
  const r = hero.getBoundingClientRect();
  samples.push([
    Math.round(performance.now() - t0),
    Math.round(r.top), Math.round(r.height),
    getComputedStyle(hero).display,
    document.styleSheets.length,
  ]);
  if (samples.length >= 50) {
    clearInterval(tick);
    navigator.sendBeacon("/api/hero-trace.json", JSON.stringify(samples));
  }
}, 100);

Trois chargements de page depuis le téléphone qui montrait le problème, et la réponse était dans les chiffres.

Ce que le relevé disait

À 12 millisecondes après le démarrage du script, le bloc principal faisait 992 pixels de haut, juste sous la barre de navigation, avec deux feuilles de style sur la page. À 114 millisecondes, il faisait zéro pixel à la position zéro, son display calculé était none, et il y avait quatre feuilles de style sur la page. À 1 554 millisecondes, il était de retour.

Rien sur la page n'ajoute de feuilles de style. Aucune règle de notre CSS ne peut mettre cet élément en display none. Aucun script de la page n'y touche. Quelque chose d'extérieur à la page injectait donc deux feuilles de style au premier chargement, et l'une d'elles cachait notre bloc principal.

Le bloc principal de ces trois pages portait les classes ad-hero, ad-heroimg et ad-sub. Le préfixe abrégeait agencies et advocacy, deux des marchés que ces pages servent. Un bloqueur de publicités ne le sait pas.

Les filtres cosmétiques masquent les éléments dont le nom de classe commence par ad-, et les bloqueurs de contenu sur iOS injectent exactement ces règles sous forme de feuilles de style au premier chargement d'une page. La seconde passe, une seconde et demie plus tard, restaurait l'élément, ce qui explique qu'il finisse par apparaître. Au rechargement, les règles du bloqueur étaient déjà en place, il n'y avait donc rien à faire clignoter.

Le correctif

Renommer trois classes. Le bloc principal s'appelle désormais mk-hero, mk-heroimg et mk-sub sur les neuf pages qui les utilisaient, dans les trois langues, et une note en tête de la feuille de style empêche quiconque de nommer une classe ainsi à l'avenir. Le correctif était en ligne douze minutes après le retour du relevé.

Afficher le code Masquer le code CSS, 3 lignes
/* Class names: never start one with "ad", "ads", "advert", "sponsor",
   "promo", "banner" or "popup". Ad blockers' cosmetic filters hide
   elements by such prefixes. */

Ce qu'il faut vérifier sur votre propre site

Ouvrez le code source de n'importe quelle page et cherchez des valeurs de class= et d'id= qui commencent par ad, ads, advert, sponsor, promo, banner ou popup. Celles que nous voyons le plus sur les sites d'associations et d'organismes à but non lucratif sont ad-banner pour une barre d'annonce, sponsor-logos pour ceux qui ont payé la conférence, et promo pour la campagne d'adhésion. Chacune est invisible pour une part significative de vos visiteurs, et vous ne le verrez jamais, parce que sur votre ordinateur tout va bien.

Et si vous avez un bogue que seuls certains visiteurs signalent et que vous ne pouvez pas reproduire, résistez à l'envie de livrer une théorie de plus. Posez une mesure sur la page pendant une journée. La mesure est plus petite que le correctif, et elle dit la vérité.

À lire ensuite

6 septembre 2026 8 minutes

Les quatre fichiers vers lesquels personne ne fait de lien

Chaque site web porte quatre fichiers texte qu'aucun visiteur ne voit jamais : robots.txt, sitemap.xml, security.txt et llms.txt. Les moteurs de recherche, les scanners de sécurité et les agents d'IA les lisent à chaque visite. Ce qu'est chacun d'eux, qui les lit vraiment, quoi y mettre, et la seule règle qui les garde tous sûrs. Nous avons repris cette liste sur notre propre site cette semaine et trouvé des manques, alors l'audit gratuit les vérifie désormais.

2 septembre 2026 7 minutes

Pourquoi la page saute pendant le chargement

Ce qu'est le décalage de mise en page et pourquoi il est perçu comme une panne, les quatre causes derrière presque tous les cas (images sans dimensions, intégrations sans espace réservé, polices qui se substituent, bandeaux injectés tard) et les correctifs exacts, y compris là où WordPress connaît déjà la largeur et la hauteur de chaque image.

Tous les articles →

Prefer to write?

Tell us what needs to work better.

Slow, fragile, hard to edit, missing a workflow. Say it plainly, and you'll get a straight answer, not a ticket number.

You'll get a straight answer, usually the same day.