Dans un précédent article, j'avais tenté d'expliquer le principe d'un serveur web et les fonctionnalités qui le caractérisent pour essayer de démystifier son fonctionnement.

Aujourd'hui je vais faire la même chose avec un navigateur web, de manière à la fois technique, tout en essayant de ne pas trop rentrer dans les détails pour garder le concept général.

Dans les faits, certains navigateurs modernes peuvent fonctionner légèrement différemment, on va donc imaginer décortiquer le fonctionnement d'un navigateur basique, comme dans les années 2000 !

La théorie

On pourrait partir du principe qu'un navigateur web, le plus basique possible n'ait que deux fonctions :

  • Envoyer des requêtes HTTP
  • Afficher un rendu graphique du contenu HTML renvoyé par le serveur web

En principe un logiciel qui implémenterait ces deux méthodes pourrait être qualifié de navigateur web sans aucun problème. Seulement avec l'état du web actuel et les attentes des utilisateurs, ce modèle théorique ne serait plus suffisant pour remplir ce job aujourd'hui.

Néanmoins il serait toujours suffisant pour afficher la première page web ayant jamais été créé par Tim Berners-Lee au CERN en 1985 et encore en ligne !

La pratique

Création d'un processus système

Lors du démarrage du navigateur, ce dernier charge automatiquement un nouvel onglet vierge. Un onglet n'est pas seulement utile pour les utilisateurs, il l'est aussi pour le fonctionnement technique du navigateur.

Lors de la création d'un onglet, le navigateur va en réalité créer un nouveau processus système (enfant) indépendant, ce qui va permettre deux choses :

  • Le navigateur et les onglets pourront continuer à communiquer, mais deux onglets ne pourront (en théorie) pas communiquer entre-eux, favorisant la sécurité.
  • Si l'un des onglets consomme trop de mémoire et doit s'arrêter, alors seul l'onglet en question pourra être terminé, et il n'y aura pas besoin de fermer tout le navigateur

Résolution DNS

Une fois l'onglet créé, une barre de navigation sera mise à disposition de l'utilisateur, laquelle devra contenir une URL valide afin que l'utilisateur puisse charger un site.

L'URL en question pourra être basée sur :

  • Un nom de domaine
  • Une adresse IP

Dans le cas où l'utilisateur indiquerait un nom de domaine, le navigateur devra aller récupérer l'adresse IP pointant sur ce dernier avant de pouvoir commencer à charger la page grâce à une requête HTTP.

Le protocole HTTP étant basé sur la suite TCP/IP, il faut forcément une adresse IP pour que le réseau puisse transporter (router) les paquets TCP.

Si vous n'êtes pas familier avec la suite de protocoles TCP/IP, je vous invite à lire mon article qui y est consacré.

Afin de récupérer l'adresse IP, le navigateur va effectuer une requête DNS (Domain Name Server aussi appelé "Système de noms de domaines") dont le seul but va être de faire une correspondance entre un nom et une IP.

Les requêtes DNS sont très fréquentes, c'est pourquoi elles sont soumises à plusieurs niveaux de cache :

  • En premier, le navigateur va aller regarder dans son cache interne pour voir si il n'a pas déjà la correspondance nom de domaine <> IP présente (et non périmée)
  • Sinon, le système d'exploitation va regarder dans son cache
  • Sinon, la requête DNS va partir sur le réseau et traverser un certain nombre de serveurs DNS récursifs (qui vont regarder dans leur cache respectif, et transmettre la requête à un autre serveur DNS le cas échéant)

Et ce jusqu'à trouver l'adresse IP correspondante, qui sera retournée en réponse à la requête.

Requête HTTP initiale

Une fois l'adresse IP correspondante au nom de domaine reçue, le navigateur va enfin pouvoir envoyer une requête HTTP pour demander la page d'accueil du site.

Lorsque l'utilisateur désire accéder au site :

google.com

Le navigateur va donc récupérer l'adresse IP :

142.250.178.142

Et agrémenter l'URL en ajoutant le protocole (http://), le port par défaut (80) et l'URI par défaut (/index.html)

http://142.250.178.142:80/index.html

La requête HTTP finale sera donc la suivante :

[HTTP/1.1] [GET] [142.250.178.142:80] [/index.html]

En réalité, la requête HTTP se fait bien avec le nom de domaine et l'IP est contenu dans paquet TCP sous-jacent, mais l'exemple ci-dessus est plus visuel.

À noter que je n'aborde pas les notions d'HTTPS et SSL ici afin de garder l'article le plus abordable possible.

Interprétation de la réponse HTTP

La réponse HTTP contient trois éléments principaux :

  • Le code de status
  • L'en-tête de la réponse
  • Le corps de la réponse
Le code de status va permettre de savoir si la requête c'est bien passée.

Le code 200 va signifier que la ressource demandée est bien présente et pourra être traitée. Le code 301 va indiquer au navigateur qu'il doit envoyer sa requête à une autre URL. Le code 404 va indiquer que la ressource demandée n'existe pas.

Si vous voulez en savoir plus sur les codes HTTP, je vous invite à lire mon article à ce sujet.

En-tête HTTP : Enregistrement des cookies

Si la réponse HTTP ne contient pas de redirection, alors les données contenues dans l'entête pourront être traitées, notamment les cookies.

Les cookies sont des données envoyées par le serveur que le navigateur devra stocker en local et renvoyer à chaque requête vers le serveur. Chaque cookie est stocké pour un domaine en particulier et pour un temps limité.

Ces cookies vont être utilisés pour avoir un suivi de l'utilisateur lors de sa navigation sur le site ou pour lui offrir des fonctionnalités qui nécessite son authentification.

Corps HTTP : Traitement

Logiquement, lorsque la requête s'est déroulé correctement, le serveur aura renvoyé une page web contenue dans le corps de la réponse HTTP, mais cette page web est alors sous la forme d'une chaine de caractère qu'il va falloir traiter.

Le navigateur, en utilisant toutes les données présentes dans la réponse, va alors devoir transformer cette chaine de caractère en un document HTML valide, en s'appuyant sur le type de document indiqué dans le premier élément présent appelé <!DOCTYPE>

<!DOCTYPE> permet de confirmer que le document reçu est bien un document HTML et il indique aussi la version du langage à utiliser (HTML5 par défaut)

L'arbre DOM (Document Object Modeling) résultant de ce traitement sera alors constitué de 2 éléments de niveaux supérieurs <head> et <body>.

Toutes les méta-données présentes dans le <head> seront d'abord traitées avant celles du <body>, c'est la raison pour laquelle les scripts chargés pendant cette partie ne peuvent pas encore avoir au corps de la page, car ce dernier n'existe pas encore.

En général c'est à ce moment que l'on charge une partie des styles CSS afin que le contenu généré dans le corps de la page soit déjà stylisé lorsqu'il sera chargé.

Une fois le corps du document chargé, il passera dans le moteur de rendu du navigateur afin de pouvoir être présenté à l'utilisateur.

Chargement des dépendances de la page

Pour chaque appel à une dépendance externe (image, feuille de style, script,...), le navigateur effectuera un nouvel appel HTTP, et chaque dépendance sera injectée (et éventuellement exécutée) dans le document HTML.

C'est une fois que ces appels sont terminés que l'on considère le chargement de la page "terminé", mais on ne sait jamais si un script ne va pas injecter dynamiquement une nouvelle dépendance à aller chercher !

Gestion du cache

Interprétation, exécution et compilation des scripts

En plus du moteur de rendu, chaque navigateur est composé d'un moteur Javascript qui va :

  • récupérer chaque script (sous forme de texte)
  • le passer dans un interpreteur syntaxique pour le transformer en code executable
  • Executer chaque script
  • Analyser l'exécution de ces derniers afin d'ajouter une compilation JIT (Just In Time)
Pour plus de détails sur le fonctionnement de la compilation Just In Time, je vous conseille de lire cet article (en anglais).

Et plus encore

Je n'ai pas parlé de l'analyse et de l'exécution du CSS et de ses animations, du cycle de rafraichissement du rendu de la page (repaint), et de bien d'autres choses, mais l'idée ici était de vous donner un aperçu du fonctionnement d'un navigateur web.

J'espère que cet article vous aura été utile, et à bientôt sur le blog !

Les articles les plus populaires du blog

Envie de continuer à lire des articles autour du développement web (entre autres) ? Voici la sélection des articles de mon blog les plus lus par la communauté !

Voir la sélection 🚀

Recevez les articles de la semaine par e-mail pour ne rien manquer !

S'abonner à la newsletter 📧

À propos de l'auteur

Hello, je suis Nicolas Brondin-Bernard, ingénieur web indépendant depuis 2015 passionné par le partage d'expériences et de connaissances.

Aujourd'hui je suis aussi coach pour développeurs web juniors, tu peux me contacter sur nicolas@brondin.com, sur mon site ou devenir membre de ma newsletter pour ne jamais louper le meilleur article de la semaine et être tenu au courant de mes projets !


Photo par Chris Ried sur Unsplash