FlowingDev

Les fichiers HAR, expliqués : la boîte noire de votre navigateur

Apprenez ce que sont les fichiers HAR (HTTP Archive), comment ils capturent chaque requête réseau de votre navigateur, et pourquoi ils sont essentiels pour débugger la performance web.

Essayer l'outil: Visualiseur HAR

En une phrase

Un fichier HAR est un journal au format JSON de l'interaction d'un navigateur avec un site, capturant chaque requête et réponse réseau dans les moindres détails pour une analyse ultérieure.

Le problème que ça résout

Imaginez la scène : un utilisateur à l'autre bout du monde vous envoie un DM : « Votre appli est d'une lenteur insupportable. » Vous l'essayez. Elle est hyper rapide. Il dit qu'elle est cassée. Vous répondez : « Ça marche sur ma machine. » Impasse.

C'est le dialogue de sourds classique du développement web. Avant les outils de navigateur modernes, débugger des problèmes réseau à distance était un cauchemar fait de suppositions, de fouilles dans les logs serveur, et de demandes à des utilisateurs non-techniques de décrire des messages d'erreur ésotériques. Même avec l'arrivée des DevTools et de leur glorieux onglet Réseau, le problème persistait : les données étaient éphémères. Impossible de les mettre en bouteille pour les envoyer à un collègue. Une capture d'écran d'un graphique en cascade ne dit pas tout.

C'est là qu'intervient le format HTTP Archive, ou HAR. Conçu par le Groupe de travail sur la performance Web du W3C, il a été pensé comme un format standard et partageable pour, eh bien, archiver les transactions HTTP. C'est l'équivalent numérique de placer une boîte noire dans le navigateur d'un utilisateur.

Un fichier HAR résout le problème du « ça marche sur ma machine » en capturant l'intégralité de la conversation réseau entre un navigateur et un serveur lors du chargement d'une page web. Il enregistre chaque requête pour une image, un script, une police ou un appel d'API. Il consigne les headers exacts envoyés, les cookies échangés, les redirections suivies et, surtout, les timings précis pour chaque étape de la requête.

Cela permet à un développeur à San Francisco de voir exactement ce qu'un utilisateur à Singapour a vécu, milliseconde par milliseconde, sans avoir à faire de suppositions. Ça rend les bugs réseau transitoires et difficiles à reproduire analysables et transforme les plaintes vagues de « lenteur » en données exploitables.

Comment ça marche sous le capot

À la base, un fichier HAR n'a rien de magique. C'est juste un gros fichier JSON bien structuré. Vous pouvez en ouvrir un dans un éditeur de texte et tout voir, bien qu'un visualiseur dédié rende la lecture infiniment plus simple. Jetons un coup d'œil à l'intérieur.

La structure globale : c'est juste du JSON

Un fichier HAR contient un seul objet JSON de haut niveau avec une seule clé : log. Tout le reste vit à l'intérieur de cet objet log.

{
  "log": {
    "version": "1.2",
    "creator": { "name": "Chrome", "version": "118.0.0.0" },
    "browser": { "name": "Chrome", "version": "118.0.0.0" },
    "pages": [ /* ... one or more page objects ... */ ],
    "entries": [ /* ... one or more request/response objects ... */ ]
  }
}
  • version : La version de la spec HAR, généralement « 1.2 ».
  • creator / browser : Des métadonnées sur l'outil et le navigateur qui ont généré le fichier. Utile pour le contexte.
  • pages : Un tableau décrivant la ou les pages principales qui ont été chargées. Il inclut le titre de la page et les timings pour des événements de haut niveau comme onLoad et onContentLoad.
  • entries : C'est la star du spectacle. C'est un long tableau où chaque objet représente une seule requête réseau et sa réponse correspondante.

La star du spectacle : le tableau entries

Quand on analyse un fichier HAR, on passe 99% de son temps dans les entries. Chaque entrée est un dossier complet sur une ressource.

Voici un aperçu simplifié d'une seule entrée :

{
  "startedDateTime": "2023-10-27T10:30:05.123Z",
  "time": 258.45,
  "request": { /* ... details of the request ... */ },
  "response": { /* ... details of the response ... */ },
  "timings": { /* ... the juicy performance breakdown ... */ },
  "pageref": "page_1"
}
  • startedDateTime : L'horodatage UTC exact du début de la requête.
  • time : Le temps total écoulé pour la requête en millisecondes, du début à la fin.
  • request : Un objet contenant tout ce que le navigateur a envoyé au serveur.
  • response : Un objet contenant tout ce que le serveur a renvoyé.
  • timings : La mine d'or pour le débuggage de performance. On va décortiquer ça juste après.
  • pageref : Un ID qui lie cette requête à l'une des pages du tableau pages.

Anatomie d'une requête et d'une réponse

Les objets request et response sont des miroirs de ce que vous verriez dans les DevTools.

L'objet request détaille :

  • method : GET, POST, PUT, etc.
  • url : L'URL complète de la ressource.
  • headers : Un tableau de tous les headers de la requête, comme User-Agent, Accept et Cookie.
  • queryString : Un tableau de tous les paramètres de requête sur l'URL.
  • postData : Pour les requêtes POST, contient le payload, comme des données de formulaire ou un corps JSON.

L'objet response détaille :

  • status : Le code de statut HTTP (ex: 200, 404, 500).
  • statusText : La phrase de statut (ex: OK, Not Found).
  • headers : Un tableau de tous les headers de la réponse, comme Content-Type, Cache-Control et Set-Cookie.
  • content : Un objet décrivant le corps de la réponse, incluant sa size, son mimeType, et souvent le corps lui-même dans la propriété text (bien que cela puisse être omis pour économiser de l'espace ou pour des raisons de sécurité).

Le détail des timings en cascade

L'objet timings est ce qui alimente le graphique en cascade coloré dans un visualiseur HAR. Il décompose le time total de la requête en ses phases constitutives. Comprendre celles-ci est la clé pour diagnostiquer « pourquoi » une requête a été lente.

Timing Ce que ça signifie
blocked Temps que la requête a passé dans la file d'attente du navigateur avant même de pouvoir commencer. Souvent dû aux limites de connexion.
dns Temps passé pour la résolution DNS. Une valeur élevée peut indiquer un fournisseur DNS lent.
connect Temps nécessaire pour établir une connexion TCP avec le serveur. Inclut le temps ssl.
ssl (Fait partie de connect) Temps pour le handshake SSL/TLS. Des valeurs élevées peuvent pointer vers des problèmes de config serveur ou de réseau.
send Temps passé à envoyer la requête HTTP au serveur. Généralement très court.
wait Time To First Byte (TTFB). C'est le plus critique. Temps passé à attendre que le serveur traite la requête et envoie le premier octet de la réponse. Un temps de wait long est presque toujours un problème de backend.
receive Temps passé à télécharger le corps de la réponse depuis le serveur. Un long temps de receive sur un petit fichier peut indiquer un réseau lent ; sur un gros fichier, c'est normal.

Le time total pour une entrée est la somme de ces timings individuels (non-négatifs). Quand un visualiseur HAR vous montre une barre pour une requête, il empile visuellement ces valeurs de timings bout à bout.

Histoires vécues

Le cas de la lenteur mystérieuse

Un PM en panique envoie un message à l'équipe : « La nouvelle page de paiement est hyper lente pour notre plus gros client ! Ils menacent de partir ! » L'équipe de dev essaie le processus de paiement. C'est ultra rapide. Le client insiste sur le fait que ça prend 20 secondes pour confirmer une commande. Au lieu d'un dialogue de sourds, le développeur principal guide le client pour exporter un fichier HAR.

En ouvrant le fichier, le problème saute aux yeux. Dans les entrées, la requête POST vers /api/v1/finalize_order a un time total de 20 145 ms. En regardant l'objet timings, le wait (TTFB) est de plus de 20 000 ms. Le serveur backend met 20 secondes à répondre. Il s'avère que ce client spécifique avait un historique de commandes massif, et une requête de base de données non optimisée expirait, mais seulement pour son compte. Le fichier HAR a fourni la preuve irréfutable qui pointait directement vers un processus backend spécifique.

La leçon à retenir : Un fichier HAR capture des conditions spécifiques à l'utilisateur (comme les données de son compte) que vous ne pouvez pas reproduire, transformant un mystère en un rapport de bug ciblé.

Le coupable : le bundle trop lourd

Un site marketing est mis en ligne et le taux de rebond crève le plafond. Le site semble tout simplement lourd. Un développeur front-end ouvre le site, ouvre les DevTools, enregistre une session et exporte le HAR.

Dans le visualiseur HAR, il trie les entrées par taille. En haut de la liste se trouve main.acb123.js avec un poids colossal de 5,2 Mo. Le graphique en cascade montre que c'est une ressource qui bloque le rendu ; rien n'apparaît sur la page tant que ce mastodonte n'a pas fini de se télécharger. Le temps de receive à lui seul est de plusieurs secondes, même sur une connexion rapide. Pire encore, en examinant les headers de la response pour cette entrée, il voit que le serveur n'envoie pas de header Content-Encoding: gzip, alors que le navigateur envoie Accept-Encoding: gzip dans les headers de la request. Le bundle JavaScript n'était pas compressé.

La leçon à retenir : Les fichiers HAR permettent de repérer avec une facilité déconcertante les tueurs de performance comme les ressources surdimensionnées et les mauvaises configurations de serveur qui assassinent le temps de chargement de votre page.

La boucle de redirection infinie

Un utilisateur se plaint de ne pas pouvoir se connecter. Il entre ses identifiants, clique sur « Se connecter » et est immédiatement renvoyé sur la page de connexion sans aucune erreur. C'est une boucle classique. Le support demande à l'utilisateur un fichier HAR de la tentative de connexion.

La liste des entries dans le HAR raconte une histoire claire :

  1. Un POST /login réussit et obtient une 302 Redirect vers /dashboard. La réponse inclut un header Set-Cookie avec le token de session.
  2. Le navigateur suit la redirection et fait une requête GET /dashboard.
  3. Le serveur répond à GET /dashboard avec une 302 Redirect qui renvoie vers /login.

Pourquoi ? Le développeur inspecte l'entrée de la requête GET /dashboard. Le header Cookie ne contient pas le token de session. Puis il vérifie la réponse du POST /login initial. Le header Set-Cookie était session_id=...; Secure; HttpOnly. Le flag Secure signifie que le navigateur n'enverra le cookie que via HTTPS. L'utilisateur était sur un environnement http://staging.example.com. Le navigateur refusait correctement d'envoyer le cookie sécurisé sur une connexion non sécurisée, donc le serveur ne le voyait jamais comme connecté.

La leçon à retenir : Les fichiers HAR vous offrent une relecture parfaite, image par image, des redirections HTTP et des échanges de headers, rendant possible le débuggage de flux d'authentification complexes qui échouent silencieusement.

Erreurs et pièges courants

  • Oublier de cocher « Conserver le journal ». Si votre bug implique de passer de la page A à la page B, vous devez activer l'option « Conserver le journal » (ou équivalent) dans les DevTools. Sinon, le journal est effacé lors de la navigation, et votre fichier HAR ne contiendra que les requêtes de la page B.
  • Partager des données sensibles. Les fichiers HAR sont des enregistreurs indiscriminés. Ils capturent les clés d'API, les tokens de session dans les cookies, et les informations personnelles identifiables dans les corps des requêtes POST. Nettoyez toujours les fichiers HAR avant de les partager dans des bug trackers publics ou des forums.
  • Mal interpréter le temps blocked. Un temps blocked élevé ne signifie pas toujours que le réseau est congestionné. Les navigateurs ont une limite sur le nombre de connexions parallèles qu'ils ouvrent vers un même domaine (généralement 6). Si vous lancez 20 requêtes d'images en même temps, 14 d'entre elles resteront à l'état blocked, en attendant que l'une des 6 premières se termine.
  • Ignorer l'état du cache. Si vous testez la performance au premier chargement, vous devez enregistrer avec le cache du navigateur désactivé. Sinon, vous verrez beaucoup de réponses 304 Not Modified ou des requêtes qui se terminent en moins d'une milliseconde, ce qui ne reflète pas l'expérience d'un nouvel utilisateur.

Pourquoi vous devriez y prêter attention

Vous devriez penser à utiliser un fichier HAR chaque fois que la communication réseau est un suspect potentiel.

  • Quand un utilisateur signale un problème de performance que vous ne pouvez pas reproduire.
  • Quand vous devez optimiser une page qui se charge lentement et que vous voulez identifier les plus gros goulots d'étranglement.
  • Quand vous débuggez un flux d'API en plusieurs étapes, comme une connexion OAuth ou un processus de paiement, et que vous avez besoin de voir la séquence exacte des événements.
  • Quand vous devez soumettre un rapport de bug à un service tiers (comme un CDN ou un fournisseur d'API) et que vous voulez leur fournir une preuve irréfutable du problème. Un fichier HAR est le langage universel des problèmes réseau.

Pour aller plus loin

Théorie bouclée. Place à la pratique — 100 % dans ton navigateur.

Essayer l'outil: Visualiseur HAR