Skip to content

Niveau 0 · Chapitre 0.3

Ce qui se passe quand une page web se charge

Taper une adresse, appuyer sur Entrée : DNS, poignées de main TCP et TLS, requête et réponse HTTP, puis analyse, mise en page et dessin, chaque étape chronométrée pour de vrai sur example.com et reliée aux appels système, interruptions et instructions qui l’exécutent.

Vous tapez example.com dans un navigateur et vous appuyez sur Entrée. Quelques dizaines de millisecondes plus tard, une page est à l’écran. Entre les deux, votre ordinateur a demandé une adresse à une chaîne de serveurs, ouvert une connexion avec une machine qu’il n’avait jamais rencontrée, convenu avec elle de clés de chiffrement, vérifié son identité, demandé une page, l’a reçue, et a transformé quelques centaines d’octets de texte en pixels.

Ce chapitre parcourt ces étapes avec de vraies mesures. Les chiffres réseau viennent de curl, qui indique combien de temps a pris chaque phase, lancé cinq fois depuis le Mac sur lequel ce chapitre a été écrit, vers https://example.com :

$ curl -s -o /dev/null -w '%{time_namelookup} %{time_connect} %{time_appconnect} %{time_starttransfer} %{time_total}\n' https://example.com
0.019641 0.026355 0.045972 0.057660 0.057712     ← first run
0.002037 0.007651 0.020672 0.035067 0.035132
0.001954 0.007644 0.019848 0.035813 0.035875
0.002150 0.008742 0.022763 0.034659 0.034760
0.002337 0.008580 0.021091 0.032697 0.032794

Chaque colonne est un instant, en secondes depuis le début : nom résolu, connexion ouverte, chiffrement prêt, premier octet de la page reçu, terminé. La différence entre deux colonnes voisines donne le coût de chaque phase :

PhasePremier essaiQuatre essais suivants
résolution DNS19,6 ms2,0–2,3 ms
poignée de main TCP6,7 ms5,6–6,6 ms
poignée de main TLS19,6 ms12,2–14,0 ms
requête → premier octet de la réponse11,7 ms11,6–16,0 ms
total57,7 ms32,8–35,9 ms

L’animation ci-dessous suit les mêmes cinq phases. La barre du bas est à l’échelle : passez de la première visite aux suivantes pour voir où le cache fait gagner du temps, et où il ne peut rien.

Voyage · Charger une page web

À essayer : Appuyez sur Lecture pour suivre l’action à travers les niveaux, ou avancez à votre rythme avec les flèches et les points.

  1. 0
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9
1 / 7Niveau 0 · Applications et utilisateur

Vous appuyez sur Entrée

Le navigateur a un nom, example.com, mais on joint les ordinateurs d’Internet par un numéro. Il lui faut d’abord l’adresse.

example.com
Où passe le temps
DNSTCPTLSHTTPtotal 57,7 ms

1. DNS : d’un nom à une adresse

Sur Internet, on joint les ordinateurs par leur adresse IP, pas par leur nom. Le DNS (Domain Name System) est l’annuaire réparti qui fait correspondre l’un à l’autre. Votre ordinateur interroge un résolveur (tenu en général par votre fournisseur d’accès, votre box ou un service public), et le résolveur fait le travail en interrogeant les serveurs le long de la hiérarchie du nom, de droite à gauche :

  1. un serveur racine sait qui est responsable de .com ;
  2. un serveur de .com sait qui est responsable de example.com ;
  3. le serveur faisant autorité pour ce domaine connaît l’adresse.

On peut jouer le résolveur à la main avec dig, en interrogeant chaque niveau sans le laisser faire la suite :

$ dig @198.41.0.4 example.com +norecurse          ← a.root-servers.net, 18 ms
com.            172800  IN  NS  l.gtld-servers.net.   …and 12 others
$ dig @192.5.6.30 example.com +norecurse          ← a.gtld-servers.net, 7 ms
example.com.    172800  IN  NS  hera.ns.cloudflare.com.
example.com.    172800  IN  NS  elliott.ns.cloudflare.com.
$ dig @hera.ns.cloudflare.com example.com +norecurse      ← 7 ms
example.com.    300     IN  A   104.20.23.154
example.com.    300     IN  A   172.66.147.243

Le nombre avant IN est le TTL, le nombre de secondes pendant lesquelles une réponse peut être gardée en cache : deux jours pour la liste des serveurs de .com, cinq minutes pour l’adresse. C’est le cache qui rend le DNS rapide. Le premier essai de curl a payé 19,6 ms de résolution ; les quatre suivants ont trouvé la réponse déjà en cache et ont payé environ 2 ms. Le domaine a aussi deux adresses IPv6, et curl a utilisé l’une d’elles, 2606:4700:10::6814:179a.

Une requête DNS est minuscule. Elle voyage en général dans un seul paquet UDP vers le port 53, et la question elle-même fait 29 octets : un en-tête de 12 octets, le nom codé en étiquettes précédées de leur longueur (7 example 3 com 0), et deux nombres de 16 bits pour le type d’enregistrement (A, une adresse IPv4) et la classe (IN, Internet). La réponse qu’a reçue dig fait 61 octets : l’en-tête, la question renvoyée telle quelle, et les deux adresses. Chaque réponse y commence par c0 0c, un pointeur de compression : au lieu de répéter example.com, il renvoie à l’octet 12, où le nom apparaît pour la première fois.

2. TCP : ouvrir une connexion

Muni d’une adresse, le navigateur ouvre une connexion TCP, un flux d’octets fiable et ordonné au-dessus d’un réseau qui perd, duplique et désordonne les paquets. L’ouvrir demande la poignée de main en trois temps : le client envoie un SYN, le serveur répond SYN-ACK, le client envoie ACK. Le client peut envoyer des données juste après son ACK, donc la poignée de main coûte un aller-retour : de 5,6 à 6,7 ms ici, ce qui est aussi à peu près le temps que met n’importe quel paquet pour atteindre ce serveur et revenir.

Pour le programme, tout cela tient en une poignée d’appels système : socket crée un point de communication, connect lance la poignée de main et bloque jusqu’à ce qu’elle aboutisse, puis write et read font circuler les octets. Tout le reste (découper le flux en paquets, les numéroter, retransmettre ceux qui se perdent, adapter le débit à la capacité du réseau) se passe dans la pile TCP/IP du noyau, comme le décrit le chapitre sur les appels système.

Sous le noyau, l’interface réseau fait le travail physique. Le pilote dépose les paquets en mémoire et la carte réseau va les chercher elle-même par DMA (accès direct à la mémoire), sans que le CPU copie quoi que ce soit ; quand des paquets arrivent, la carte les écrit en mémoire et déclenche une interruption, comme le décrit le chapitre sur les déroutements et les interruptions. La façon dont les bits traversent le câble ou l’air fait l’objet du chapitre sur les modems et Ethernet.

L’image classique de ce chemin est la même dans l’esprit : le navigateur confie une requête HTTP à TCP, qui ajoute un en-tête et la passe à IP, qui en ajoute un autre, jusqu’à la couche liaison et sa somme de contrôle. Il y a dix ans, on se connectait à Internet chez soi en ADSL sur la ligne téléphonique, et l’Ethernet à 40 gigabits était encore à venir. Aujourd’hui l’accès domestique passe surtout par la fibre, le câble ou le réseau mobile, et les centres de données font tourner de l’Ethernet à 400 et 800 Gbit/s.

3. TLS : un canal privé et authentifié

Le https de l’adresse signifie que la connexion doit être chiffrée et que le serveur doit prouver qui il est. C’est le rôle de TLS (Transport Layer Security). Le client de test d’OpenSSL montre ce qui a été convenu avec ce serveur :

$ openssl s_client -connect example.com:443 -brief
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=example.com
Signature type: ecdsa_secp256r1_sha256
Negotiated TLS1.3 group: X25519MLKEM768
  • TLS 1.3 a besoin d’un aller-retour pour sa poignée de main. Dans le tableau, elle a pris 12 à 14 ms : cet aller-retour, plus le calcul des deux côtés : générer et combiner les clés, vérifier la signature du serveur et ses certificats.
  • X25519MLKEM768 est l’échange de clés : les deux côtés conviennent d’un secret commun que personne ne peut calculer en observant le trafic. C’est un hybride entre une méthode classique à courbe elliptique (X25519) et ML-KEM, une méthode plus récente conçue pour résister aux futurs ordinateurs quantiques, un changement devenu le comportement par défaut des navigateurs et des serveurs il y a peu.
  • Le certificat dit « cette clé publique appartient à example.com », signé par une autorité de certification, dont le propre certificat est signé par une autre, jusqu’à une racine en laquelle votre système d’exploitation a confiance. Cette chaîne-ci compte quatre certificats, et celui du site est valable 90 jours.
  • AES-256-GCM est l’algorithme de chiffrement qui protège chaque octet après la poignée de main.

C’est avec AES que les niveaux les plus bas se montrent. Les CPU modernes ont des instructions qui réalisent un tour de chiffrement AES sur 16 octets en une seule étape : AES-NI sur x86, les extensions cryptographiques sur ARM. Le banc d’essai d’OpenSSL, sur un cœur de ce Mac, montre ce qu’elles valent :

AES-256-GCM sur des blocs de 16 KoDébit
avec les instructions AES d’ARM7,4–7,5 Go/s
sans elles (OPENSSL_armcap=0)168–169 Mo/s

Un facteur 44. Avec les instructions dédiées, chiffrer une page web ne coûte presque rien ; sans elles, une connexion réseau rapide occuperait un cœur à plein temps. Le principe selon lequel matériel et logiciel sont logiquement équivalents se voit ici : le même algorithme, en logiciel ou dans le silicium, ne diffère que par la vitesse. Le curl du système sur ce Mac, construit sur une autre bibliothèque TLS, a négocié ChaCha20-Poly1305 à la place, un chiffrement conçu pour être rapide avec de simples additions, XOR et rotations ; OpenSSL l’exécute à environ 1,9 Go/s sur le même cœur.

4. HTTP : la requête et la réponse

Ce n’est que maintenant que le navigateur demande la page. Sur le canal chiffré, il envoie une requête HTTP, et curl -v montre les deux côtés (en-têtes de réponse abrégés) :

> GET / HTTP/2
> Host: example.com
> User-Agent: curl/8.7.1
> Accept: */*

< HTTP/2 200
< content-type: text/html; charset=utf-8
< server: cloudflare
< age: 9217
< cf-cache-status: HIT

200 signifie succès. Le protocole est HTTP/2, choisi pendant la poignée de main TLS : il envoie les en-têtes sous une forme binaire compacte et peut transporter plusieurs requêtes à la fois sur une même connexion. La version la plus récente, HTTP/3, fonctionne sur QUIC, au-dessus d’UDP, et fusionne les poignées de main du transport et de TLS pour économiser un aller-retour.

Les en-têtes révèlent aussi que la machine qui répond n’est pas du tout « le » serveur d’example.com. cf-cache-status: HIT et age: 9217 indiquent qu’un serveur de CDN (réseau de diffusion de contenu) proche de ce Mac a servi une copie qu’il gardait depuis environ deux heures et demie. La plupart des sites populaires fonctionnent ainsi : la page vient d’un cache situé à quelques millisecondes plutôt que d’un serveur d’origine lointain. Les 11,6 à 16 ms avant le premier octet, c’est un aller-retour pour la requête plus le temps que met le serveur à trouver la réponse.

Le corps fait 713 octets de HTML : un titre, une courte feuille de style, un paragraphe, un lien, et une balise <script> qui pointe vers un petit script, /s.js, que le navigateur devra aller chercher avec une deuxième requête.

5. Des octets aux pixels

C’est maintenant que commence le travail propre au navigateur. Dans Chrome, chaque site s’exécute dans son propre processus de rendu, isolé du reste du système dans un bac à sable ; une instance de Chrome sur ce Mac tournait sous la forme de huit processus : le navigateur lui-même, un processus GPU, un service réseau, un service de stockage et quatre processus de rendu. Le processus de rendu :

  1. analyse le HTML pour en faire un arbre d’éléments, le DOM (Document Object Model), et le CSS pour en tirer des règles de style ;
  2. exécute le JavaScript de la page, qui peut modifier les deux (ici, le seul petit script) ;
  3. calcule le style de chaque élément, puis fait la mise en page (layout) : la position et la taille de chaque boîte, et les retours à la ligne de chaque paragraphe, ce qui demande la mise en forme du texte décrite dans le chapitre sur la frappe ;
  4. dessine (paint) : transforme les boîtes, les bordures et le texte en commandes de dessin ;
  5. confie le résultat au compositeur, qui le rastérise, souvent sur le GPU, et l’affiche au prochain rafraîchissement de l’écran.

Pour une vraie page, cette étape se répète à mesure qu’arrivent ses autres ressources : chaque image, feuille de style, script et police est une requête de plus, souvent vers d’autres domaines, chacun avec sa résolution DNS, sa connexion et sa poignée de main TLS. Une page d’actualité ou de boutique typique fait des dizaines à des centaines de requêtes. C’est pourquoi les navigateurs gardent les connexions ouvertes pour les réutiliser, mettent en cache à tour de bras, et lancent à l’avance les requêtes pour les ressources qu’ils prévoient avant même que la page les demande.

Où se montrent les niveaux

ÉtapeCe qui l’exécute
socket, connect, write, readdes appels système vers la pile TCP/IP du noyau
paquets entrants et sortantsle DMA de la carte réseau, puis une interruption
attendre le réseaule processus est bloqué ; l’ordonnanceur exécute autre chose
chiffrement AES-GCMles instructions AES dédiées de l’ISA
échange de clés et signaturesde l’arithmétique sur de grands nombres, compilée depuis du C et de l’assembleur
analyse du HTML et mise en pagedu code ordinaire, dont la vitesse dépend des caches et de la prédiction de branchement
le moteur de renduun processus séparé, dans un bac à sable
dessin et compositionle GPU et le rafraîchissement de l’écran

L’essentiel des 33 ms est de l’attente : trois allers-retours d’environ 6 ms vers le serveur (pour TCP, TLS et HTTP), plus la résolution DNS, qui en coûte plusieurs de plus quand la réponse n’est pas en cache. Pendant ce temps, le CPU ne fait presque rien pour cette page. La lumière va dans la fibre à environ 200 000 km/s, deux tiers de sa vitesse dans le vide, donc chaque tranche de 1 000 km entre vous et un serveur ajoute au moins 10 ms à chaque aller-retour. Aucun processeur plus rapide n’y change rien ; la réponse est d’avoir besoin de moins d’allers-retours (TLS 1.3, HTTP/3, connexions réutilisées) et de rapprocher le serveur (les CDN).

À retenir

  • Charger une page, c’est le DNS (du nom à l’adresse), TCP (une connexion fiable), TLS (chiffrement et identité), HTTP (requête et réponse), puis analyse, mise en page et dessin dans le navigateur.
  • Mesuré sur example.com : environ 2 ms de DNS en cache (20 ms sans cache), 6 ms par aller-retour, 12–14 ms de TLS, environ 33 ms en tout.
  • Le cache est partout : les réponses DNS portent un TTL, et un CDN a servi cette page à partir d’une copie vieille de 2 h 30.
  • TLS 1.3 a utilisé ici un échange de clés hybride post-quantique et AES-256-GCM, que les instructions AES du CPU exécutent 44 fois plus vite que du code ordinaire.
  • Pour le programme, le réseau, ce sont quelques appels système ; la pile TCP/IP du noyau, le DMA et les interruptions font le reste.
  • L’essentiel du temps passe à attendre des allers-retours : les grands gains viennent de moins d’allers-retours et de serveurs plus proches, pas de CPU plus rapides.

Dans ce niveau

  1. 0.1Ce qui se passe quand on ouvre une application
  2. 0.2De la touche au pixel
  3. 0.3Ce qui se passe quand une page web se charge
  4. 0.4Applications, processus et fichiers
  5. 0.5Pourquoi mon ordinateur est-il lent ?