Retour au blog

Votre script d'analytics désactive probablement le cache de navigation arrière/avant

Le cache de navigation arrière/avant rend les retours en arrière quasi instantanés, mais un seul listener unload le désactive pour toute la page. Les scripts de tracking sont les coupables habituels — et le CrUX mesure désormais les dégâts.

La navigation la plus rapide du web est celle où rien ne se charge. Le cache de navigation arrière/avant (bfcache) offre exactement ça — et une seule ligne dans le script de votre fournisseur d'analytics peut le couper pour chaque page de votre site.

Le bfcache est une optimisation du navigateur qui conserve en mémoire un instantané complet d'une page — heap JavaScript inclus — quand l'utilisateur quitte la page. Appuyez sur le bouton retour et le navigateur restaure cet instantané puis reprend l'exécution, produisant un chargement quasi instantané sans aucune requête réseau. Les navigations arrière et avant représentent environ 10 à 20 % de toutes les navigations, ce n'est donc pas un cas marginal.

Un seul listener disqualifie toute la page

L'éligibilité au bfcache est fragile par conception. Le navigateur ne gèlera pas une page qui a enregistré un listener d'événement unload, car unload implique que la page s'attend à être détruite. Sur desktop, Chrome et Firefox rendent toute page avec un listener unload inéligible au bfcache — aucune exception, aucun demi-crédit.

Le listener n'a pas à être le vôtre. Les scripts tiers qui enregistrent unload depuis l'intérieur de votre page, voire à l'intérieur d'une sous-frame, disqualifient le document de premier niveau. Lighthouse embarque un audit dédié no-unload-listeners précisément parce que le code fautif est si souvent du code que l'auteur du site n'a jamais écrit.

beforeunload n'est plus disqualifiant dans les navigateurs modernes, mais il reste peu fiable et toujours à éviter à moins qu'un utilisateur n'ait des modifications non enregistrées.

Les scripts de tracking sont les coupables habituels

L'événement unload est l'endroit classique pour envoyer un dernier beacon — vider une session, envoyer un événement « page fermée » — alors les scripts de tracking comportemental et publicitaires s'y précipitent constamment.

Le fbevents.js de Facebook enregistre un handler unload et apparaît sur environ 9 % de toutes les pages web d'après HTTP Archive. Le tag de PayPal injecte une iframe qui ajoute un événement unload, bloquant le bfcache sur de nombreux parcours de paiement. Des scripts en sous-frame comme hCaptcha ont fait la même chose. Aucun d'entre eux ne nécessite une modification de votre propre code pour commencer à vous coûter cher — il suffit qu'un fournisseur pousse une mise à jour.

Le CrUX vous présente désormais la facture

Cela était autrefois invisible dans les données de terrain. Depuis le jeu de données de mars 2024, le Chrome User Experience Report (CrUX) rapporte une ventilation navigation_types — y compris la part des visites servies depuis le cache de navigation arrière/avant — pour que vous puissiez voir combien d'utilisateurs réels passent à côté du chemin instantané.

La corrélation est frappante. L'analyse CrUX a trouvé une forte relation statistique (ρ=0,87) entre une part élevée de back_forward_cache et la instant_lcp_density — la proportion de chargements avec un LCP sous 200 ms. Après la mise à jour de Google en mars 2026 qui a relevé le poids du LCP, de l'INP et du CLS dans le classement, un blocage de bfcache auto-infligé est un désavantage mesurable au 75e centile, pas une erreur d'arrondi.

Le détecter et le corriger

Ouvrez les DevTools, allez dans Application → Back/forward cache, et cliquez sur Run Test. Chrome liste chaque raison de blocage, y compris les handlers unload ajoutés par des tiers.

Pour détecter les restaurations bfcache dans votre propre code, n'utilisez jamais unload. Utilisez pageshow et vérifiez persisted :

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // restored from bfcache — no fresh page load fired
  }
})

Pour empêcher des tiers de vous disqualifier, définissez un en-tête de réponse qui interdit complètement les listeners unload :

Permissions-Policy: unload=()

Cela neutralise les handlers unload de n'importe quel script — tags de fournisseurs, extensions, ou votre propre code hérité — pour que la page reste éligible au bfcache quoi qu'il se charge.

Le tracker qui n'y touche jamais

La correction structurelle consiste à utiliser une instrumentation qui n'a aucune raison d'écouter unload au départ. Un tracker privacy-first enregistre une vue de page avec une seule requête keepalive et laisse la requête survivre à la page d'elle-même — pas de beacon de fermeture, pas de handler unload, rien que le navigateur puisse signaler :

fetch('/collect', {
  method: 'POST',
  keepalive: true,
  body: JSON.stringify({ site_id, path: location.pathname })
})

Quand un tracker doit réagir au passage d'une page en arrière-plan, le bon signal est visibilitychange ou pagehide, qui se déclenchent tous deux sans rendre la page inéligible au bfcache. Le tracker de Monoid fait environ 2 Ko, ne pose aucun cookie, et s'accroche à history.pushState pour les changements de route en SPA plutôt qu'au cycle de vie de la page — il n'a donc aucun listener unload à enregistrer et rien pour désactiver votre cache de navigation arrière/avant.

L'analytics de surveillance taxe la performance de manières qui n'apparaissent pas dans un test en laboratoire. Un blocage du bfcache est l'un des plus silencieux : pas d'erreur, pas de rendu lent, juste un bouton retour qui recharge depuis le réseau alors qu'il aurait dû restaurer depuis la mémoire.

Sources

Comments

Loading comments…