Au cœur du navigateur Web moderne (partie 2)

Mariko Kosaka

Que se passe-t-il pendant la navigation ?

Cet article est le deuxième d'une série de quatre articles de blog consacrée aux rouages de Chrome. Dans l'article précédent, nous avons vu les différences les processus et les threads gèrent différentes parties d'un navigateur. Dans cet article, nous approfondissons la façon dont chaque processus et chaque fil communiquent afin d’afficher un site web.

Examinons un cas d'utilisation simple de la navigation Web: vous saisissez une URL dans un navigateur, puis le navigateur récupère des données sur Internet et affiche une page. Dans cet article, nous nous intéresserons à la partie un utilisateur demande un site et le navigateur se prépare à afficher une page, c'est-à-dire une navigation.

Cela commence par un processus de navigateur

Processus du navigateur
Figure 1: Interface utilisateur du navigateur en haut, schéma du processus du navigateur avec UI, réseau et stockage fil de discussion en bas

Comme nous l'avons vu dans Partie 1: Processeur, GPU, mémoire et architecture multiprocessus, tout ce qui se trouve en dehors d'un onglet est géré par le processus du navigateur. Le processus du navigateur comporte des threads comme le thread UI qui dessine les boutons et les champs de saisie des le navigateur, le thread réseau qui traite de la pile réseau pour recevoir des données depuis Internet, le thread de stockage qui contrôle l'accès aux fichiers, etc. Lorsque vous saisissez une URL dans l'adresse votre entrée est gérée par le thread UI du processus du navigateur.

Une navigation simple

Étape 1: Traiter les entrées

Lorsqu'un utilisateur commence à saisir du texte dans la barre d'adresse, la première chose que demande le thread UI est "Est-ce un requête de recherche ou l'URL ?". Dans Chrome, la barre d'adresse est aussi un champ de saisie de recherche. Le thread UI doit analyser et décider de vous rediriger vers un moteur de recherche ou vers le site demandé.

Traiter les entrées utilisateur
Figure 1: Thread UI demandant si l'entrée est une requête de recherche ou une URL

Étape 2: Démarrez la navigation

Lorsqu'un utilisateur appuie sur Entrée, le thread UI lance un appel réseau pour obtenir le contenu du site. Icône de chargement s'affiche dans le coin d'un onglet et le thread réseau passe par les protocoles appropriés tels que résolution DNS et établissant une connexion TLS pour la requête.

Démarrage de la navigation
Figure 2: thread UI communiquant au thread réseau pour accéder à monsite.com

À ce stade, le thread réseau peut recevoir un en-tête de redirection du serveur tel que HTTP 301. Dans ce cas, le thread réseau communique avec le thread UI que le serveur demande une redirection. Ensuite, une autre demande d'URL sera lancée.

Étape 3: Lisez la réponse

Réponse HTTP
Figure 3: En-tête de réponse contenant Content-Type et payload, qui correspondent aux données réelles

Une fois que le corps de la réponse (charge utile) commence à arriver, le thread réseau examine les premiers octets du flux si nécessaire. L'en-tête Content-Type de la réponse devrait indiquer le type de données, mais comme il peut être manquant ou faux, Reniflage de type MIME est effectuée ici. Il s'agit d'une tâche complexe. comme indiqué dans le code source. Vous pouvez lire le commentaire pour voir comment les différents navigateurs traitent les paires contenu-type/charge utile.

Si la réponse est un fichier HTML, l'étape suivante consiste à transmettre les données au moteur de rendu. mais s'il s'agit d'un fichier ZIP ou d'un autre type de fichier, il s'agit d'une demande de téléchargement. ils doivent transmettre les données au gestionnaire de téléchargement.

Reniflage de type MIME
Figure 4: Thread réseau demandant si les données de réponse proviennent d'un site sécurisé en HTML

C'est également à ce niveau que le contrôle de la SafeBrowsing est effectué. Si le domaine et les données de réponse semblent correspondre à un site malveillant connu, le thread réseau des alertes pour afficher une page d'avertissement. En outre, Cross Origin Block (CORB) pour s'assurer que les données sensibles intersites ne sont pas transmises au processus du moteur de rendu.

Étape 4: Trouver un processus de moteur de rendu

Une fois que toutes les vérifications ont été effectuées et que le fil de discussion du réseau est sûr que le navigateur doit accéder à la demandé, le thread réseau indique au thread UI que les données sont prêtes. Le thread UI trouve ensuite du moteur de rendu pour poursuivre l'affichage de la page Web.

Processus de recherche du moteur de rendu
Figure 5: Thread réseau demandant au thread UI de trouver le processus du moteur de rendu

Étant donné que la requête réseau peut prendre plusieurs centaines de millisecondes pour obtenir une réponse, une pour accélérer ce processus. Lorsque le thread UI envoie une requête d'URL à le thread réseau à l'étape 2, il sait déjà vers quel site ils accèdent. Thread UI tente de trouver ou de démarrer de manière proactive un processus de moteur de rendu en parallèle de la requête réseau. De cette façon, Si tout se passe comme prévu, un processus de moteur de rendu est déjà en position de veille lorsque le thread réseau des données reçues. Ce processus de secours peut ne pas être utilisé si la navigation redirige vers un site auquel cas un processus différent peut être nécessaire.

Étape 5: Validez la navigation

Maintenant que les données et le processus du moteur de rendu sont prêts, une IPC est envoyée du processus du navigateur à du moteur de rendu pour valider la navigation. Il transmet aussi le flux de données, peut continuer à recevoir des données HTML. Une fois que le processus du navigateur entend la confirmation que le commit s'est produite dans le processus du moteur de rendu, la navigation est terminée et la phase de chargement du document commence.

À ce stade, la barre d'adresse est mise à jour, et l'indicateur de sécurité et l'UI des paramètres du site reflètent les les informations de site de la nouvelle page. L'historique des sessions de l'onglet sera mis à jour. les boutons parcouriront le site auquel l’utilisateur vient d’accéder. Pour faciliter la restauration des onglets/sessions lorsque vous fermez un onglet ou une fenêtre, l'historique de la session est stocké sur le disque.

Valider la navigation
Figure 6: IPC entre les processus du navigateur et du moteur de rendu, demande d'affichage de la page

Étape supplémentaire: chargement initial terminé

Une fois la navigation validée, le processus de moteur de rendu continue de charger les ressources et affiche . Nous reviendrons sur ce qu'il se passe à ce stade dans le prochain post. Une fois que le moteur de rendu processus "finishes" le rendu, il renvoie une IPC au processus du navigateur (c'est-à-dire une fois les événements onload ont été déclenchés sur tous les frames de la page et leur exécution est terminée). À ce stade, le thread UI arrête l'icône de chargement de l'onglet.

Je dis "finishes", car le JavaScript côté client peut quand même se charger. des ressources supplémentaires et afficher de nouvelles vues par la suite.

Chargement de la page terminée
Figure 7: IPC depuis le moteur de rendu jusqu'au processus du navigateur pour avertir que la page est "chargée"

La navigation simple était terminée ! Mais que se passe-t-il si un utilisateur place une URL différente dans la barre d'adresse ? encore ? Le processus du navigateur suit les mêmes étapes pour accéder à l'autre site. Mais avant de pouvoir faire cela, il doit vérifier auprès du site actuellement affiché s'il est intéressé beforeunload.

beforeunload peut créer l'option "Quitter ce site ?" lorsque vous essayez de quitter l'onglet ou de le fermer. Tout ce qui se trouve dans un onglet, y compris votre code JavaScript, est géré par le processus du moteur de rendu. le processus du navigateur doit vérifier avec le processus actuel du moteur de rendu lorsqu'une nouvelle requête de navigation arrive.

gestionnaire d'événements beforeunload
Figure 8: IPC entre le processus du navigateur et le processus du moteur de rendu indiquant qu'il est sur le point de accéder à un autre site

Si la navigation a été lancée à partir du processus du moteur de rendu (par exemple, si l'utilisateur a cliqué sur un lien ou le code JavaScript côté client a exécuté window.location = "https://newsite.com") le processus du moteur de rendu vérifie d'abord les gestionnaires beforeunload. Ensuite, il passe par le même processus que le processus du navigateur. la navigation. La seule différence est que la requête de navigation est lancée à partir de au processus du navigateur.

Lorsque la nouvelle navigation renvoie vers un site différent de celui actuellement affiché, un affichage distinct est appelé pour gérer la nouvelle navigation, tandis que le processus de rendu actuel est maintenu gérer des événements tels que unload. Pour en savoir plus, consultez Présentation des états du cycle de vie des pages. et comment vous connecter à des événements avec l'API Page Lifecycle.

nouvelle navigation et décharger
Figure 9: Deux IPC entre un processus de navigateur et un nouveau processus de moteur de rendu indiquant d'afficher la page et demander à l'ancien processus de moteur de rendu de décharger

Cas d'un service worker

Un changement récent de ce processus de navigation est l'introduction de service worker ; Un service worker permet d'écrire un proxy réseau dans le code d'application ; ce qui permet aux développeurs Web de mieux contrôler ce qu'ils mettre en cache localement et quand obtenir de nouvelles données du réseau. Si le service worker est configuré pour charger la page du cache, il n'est pas nécessaire de demander les données au réseau.

Ce qu'il faut retenir, c'est que le service worker est un code JavaScript qui s'exécute dans un moteur de rendu. processus. Mais lorsque la demande de navigation arrive, comment un processus de navigateur sait-il que le site a un un service worker ?

Recherche de champ d'application de service worker
Figure 10: Thread réseau dans le processus de navigateur recherchant le champ d'application du service worker

Lorsqu'un service worker est enregistré, son champ d'application est conservé en tant que référence. Pour en savoir plus sur la portée, (article Cycle de vie d'un service worker). Lorsqu'une navigation a lieu, le thread réseau vérifie le domaine par rapport au service worker enregistré si un service worker est enregistré pour cette URL, le thread UI trouve un processus de moteur de rendu dans pour exécuter le code d'un service worker. Le service worker peut charger des données à partir du cache, ce qui élimine le besoin de demander des données au réseau, ou il peut demander de nouvelles ressources au réseau.

navigation de serviceworker
Figure 11: Thread UI d'un processus de navigateur qui lance un processus de moteur de rendu pour gérer le service les nœuds de calcul ; un thread de travail dans un processus de moteur de rendu demande ensuite des données au réseau

Vous pouvez voir que cet aller-retour entre le processus du navigateur et celui du moteur de rendu peut entraîner des retards si le service worker décide finalement de demander des données au réseau. Le préchargement de navigation est un mécanisme qui permet d'accélérer en chargeant les ressources en parallèle du démarrage du service worker. Il marque ces requêtes avec un en-tête, ce qui permet aux serveurs de décider d'envoyer un contenu différent pour ces demandes, par exemple, simplement mettre à jour des données au lieu d’un document complet.

Préchargement de navigation
Figure 12: Thread UI d'un processus de navigateur qui lance un processus de moteur de rendu pour gérer le service lors du lancement d'une requête réseau en parallèle

Conclusion

Dans ce post, nous avons vu ce qui se passe lors d'une navigation et comment votre application Web code telle comme les en-têtes de réponse et le code JavaScript côté client qui interagissent avec le navigateur. Connaître les étapes du navigateur pour récupérer les données du réseau, il est plus facile de comprendre pourquoi des API telles que la navigation ont été développées. Dans le prochain message, nous verrons comment le navigateur évalue HTML/CSS/JavaScript pour afficher les pages.

Avez-vous apprécié ce post ? Si vous avez des questions ou des suggestions pour le prochain post, n'hésitez pas à dans la section des commentaires ci-dessous ou en envoyant @kosamari sur Twitter.

Étape suivante: Fonctionnement interne d'un processus de moteur de rendu