Performance : essayons de comprendre comment les sites web sollicitent les différentes parties d’un navigateur (ou la genèse de l’architecture d’IE9)

Comme je vous l'indiquais dans ce 1er article lors de la PDC09, nous avions vu de quelles manières nos navigateurs étaient sollicités dans des scénarios réels. Les sites web stressent de manière différente les différentes couches du navigateur. Aussi, pour construire un navigateur rapide dans des contextes réels, il faut commencer par comprendre les différents scénarios d’usage des utilisateurs. Dans cet article, nous allons voir comment l’ensemble des sous-systèmes du navigateurs impactent les performances globales à travers 5 sites web actuellement en production et représentant des cas classiques de notre navigation de tous les jours. Nous avons utilisé Internet Explorer 8 pour construire l’analyse présentée ci-dessous.

Tous les navigateurs modernes sont conceptuellement similaires. Les concepteurs de ces navigateurs ont cependant des priorités différentes. Par exemple, certains se fixent comme objectif de supporter plusieurs systèmes d’exploitation plutôt que d’optimiser son navigateur pour un OS unique, implémenter plutôt telle partie de HTML5 plutôt qu’une autre (et on sait qu’HTLM5 est un chantier qui prendra plusieurs années !), etc. Cela amène donc déjà naturellement à des différences entre chacun navigateur. Les éditeurs ont également plusieurs approches de conception des moteurs. Ces approches découlant d’ailleurs en partie des priorités qu’ils se fixent. En effet, il est logique de concevoir un moteur de manière différente si l’on vise plusieurs OS et si l’on tente de factoriser au maximum les branches de code. Mais si l’on prend un peu de recul sur ces détails d’implémentation techniques, tous les nouveaux navigateurs finalement se connectent à un serveur et tentent de nous proposer le même genre d’expérience en exécutant si possible le même markup et le même script.

Les sous-systèmes d’Internet Explorer
Internet Explorer est ainsi composé de 11 sous-systèmes ou composants principaux. Tous les navigateurs récents proposent le même genre de capacités. Mais bien que les noms de ces modules puissent légèrement varier d’un navigateur à un autre, le processus global reste quasiment identique.Progression of IE subsystems. Networking --> HTML --> CSS --> Collections --> Javascript --> Marshalling --> Native OM --> Formatting --> Block Building --> Layout --> Display

Voici un rapide descriptif de ces composants dans l’ordre dans lesquels ils sont rencontrés lorsque vous chargez un site web :

Réseaux : naturellement, le 1er sous-système généralement sollicité est celui gérant le réseau. Le composant réseau est en charge de toutes les communications entre le client et le serveur, en incluant la gestion du cache local du contenu web. Le composant réseau est donc généralement fortement lié aux performances du réseau de l’utilisateur.

HTML : une fois les documents HTML téléchargés depuis le serveur, ils sont fournis au composant HTML qui analyse le document, lance des téléchargements supplémentaires (images, CSS, etc.) à travers le composant réseau puis en créé une représentation logique en mémoire.  Les navigateurs les plus récents contiennent également des composants connexes utilisés pour les documents XHTML, le XML et SVG.

CSS : une fois qu’une feuille de style CSS est rencontrée (que ce soit au sein du document HTML ou dans un fichier à part), elle est passée au composant CSS qui analyse les informations qui y sont contenues et en créé une représentation logique en mémoire qui sera utilisée plus tard. 

Collections : les documents HTML contiennent très souvent des métadonnées comme par exemple les informations fournies en entête ou les attributs appliqués à un élément.  Ce composant est responsable de stocker et d’accéder à ces métadonnées.

JavaScript : lorsqu’un morceau de script est trouvé, il est passé directement au composant en charge du JavaScript qui est tout naturellement responsable d’exécuter ce dernier. C’est certainement le composant le plus connu d’un navigateur de part la visibilité que ce dernier a reçu ces dernières années vu que l’on pensait qu’il était au centre des performances des nouveaux sites à base d’AJAX ou jQuery. Sans compter le marketing actif effectué autour des benchmarks tel que le SunSpider. Marshaling : comme certains moteurs JavaScript ne sont pas directement intégrés au navigateur,il y a une couche de communication entre le navigateur et le moteur de script. Le fait de passer à travers cette couche de communication est généralement appelé “Marshalling”. Notion que l’on retrouve aussi dans d’autres passages de barrières : passage de types de .NET vers COM par exemple, 2 mondes radicalement différents.

Modèle objet : le code JavaScript interagit avec le document à travers les APIs du DOM (Document Object Model). Ces APIs sont généralement fournies à travers un composant qui sait comment accéder et manipuler le document créé lors d’une phase précédente. C’est le point principal d’interaction entre le moteur de script et le navigateur.

Formatage : une fois le document construit, le navigateur doit lui appliquer les informations de style avant qu’il soit affiché à l’utilisateur. Ce composant prend le document HTML construit en mémoire et lui applique les styles trouvés.

Construction des Blocs : CSS est un système basé sur des blocs. Une fois les styles appliqués au document, l’étape d’après est de construire des blocs rectangulaires qui seront affichés à l’utilisateur. Ce processus détermine certaines choses comme la taille de ces blocs et est intiment lié à la prochaine étape : la mise en page.

Mise en page : maintenant que le navigateur a appliqué les styles et construit les blocs, il peut démarrer le processus de mise en page du contenu. C’est un processus qui implique des traitements algorithmiques relativement complexes.

Rendu : la dernière étape du processus global incombe au composant en charge du rendu. Cette étape est souvent vue comme celle où l’on “dessine à l’écran” et peut être traitée soit par le CPU, soit par le GPU, soit une combinaison des 2.

Comme nous l’avons déjà dit, les différents sites vont stresser ces différents composants de différentes manières. C’est le cas de certains sites d’informations les plus connus au monde et proposant pourtant des fonctionnalités similaires. Ces derniers exposent une expérience comparable sur leur page d’accueil incluant par exemple de la vidéo et une mise en page relativement complexe. Cependant, ils affichent des performances assez différentes.

Analyse de sites d’informations connus
Afin de vous aider à mieux comprendre tout cela, nous avons pris les 5 plus gros sites web d’informations au monde. Nous avons ensuite utilisé IE8 pour en effectuer un profilage grâce aux outils de performance Windows. Nous avons effectué l’ensemble dans un environnement contrôlé pour retirer les variables externes et nous avons chargé chacun des sites plusieurs fois pour s’assurer d’avoir les résultats les plus fidèles possibles. Nous avons ensuite retiré du tableau tout ce qui était lié aux performances réseaux car ces dernières sont trop fortement dépendantes du contexte de l’utilisateur (sa bande passante et la qualité globale de son accès internet).

Cette approche nous a permis de voir le temps total qu’il a fallut au navigateur pour charger un site web puis de diviser ce temps CPU entre les différents composants. Dans le graphique ci-dessous, vous pouvez voir qu’il a fallut entre 1117 et 3704 millisecondes pour charger ces 5 pages. Chacune des couleurs représente le temps passé dans chacun des sous-systèmes.

Chart of subsystem Breakdownfor Common News Sites

Il y a des modèles assez révélateurs qui se dégagent dans ces résultats. Par exemple, le 1er site passe la majorité de son temps dans le composant JavaScript, le 2ème site passe le plus clair de son temps dans le composant de Marshalling tant dis que le 5ème site passe plus de temps sur le processus global de mise en page et de rendu (la somme des blocs violet, orange, vert et jaune). Pour chacun des sites web, des combinaisons différentes des composants ont eu un impact maximum sur les performances globales.

Il est également intéressant de noter que le développeur web a logiquement énormément d’impact sur les performances globales de son propre site. Ainsi, bien que le 3ème site d’informations fourni une expérience comparable à ses concurrents, ils suivent de bonnes pratiques pour améliorer les performances. Le site est ainsi chargé en à peine plus d’1 seconde. En comparaison, le 4ème site ne suit pas beaucoup de ces bonnes pratiques et prend plus de 3 fois plus de temps à charger. Bien qu’il soit difficile de comparer 2 sites qui ne proposent pas strictement le même contenu sur la même stack logicielle (ASP.NET ou PHP ? IIS ou Apache ?) ou le même matériel, cela montre malgré tout que pour l’utilisateur la perception entre 2 sites similaires peut être énorme car les développeurs n’auront pas assez travaillé sur son optimisation. N’oublions donc pas que le navigateur n’est que le bout de la chaîne.

Lorsque l’on tente de synthétiser l’ensemble de ces résultats, on peut alors voir se dessiner l’impact relatif de chacun des composants à travers les différents sites web. Comme vous pouvez le voir ci-dessous, chaque sous-système joue un rôle important sur les performances. Cependant, le module JavaScript consommant 29% du temps, celui du Marshalling 18% et celui du rendu 17%, ils représentent à eux seuls l’impact le plus large et donc ceux sur lesquels il peut apparaître important de travailler en 1er.

Chart of amount of time inside each browser subsystem on News Sites

Profilange des top sites AJAX

Les sites d’informations fournissent une vue intéressante sur le côté multidimensionnel des performances. Cependant, il reste important d’analyser d’autres types de sites web et d’en analyser les modèles s’en dégageant. Lorsque nous lançons ainsi la même analyse sur les 25 plus gros sites AJAX, incluant certaines des applications JavaScript les plus sophistiquées comme Facebook, Gmail et Hotmail, nous obtenons les résultats suivants :

Chart of Amount of time inside each browser subsystem on AJAX sites

Comme vous pouvez le voir, la distribution a légèrement changé. Certains composants comme HTML, CSS et JavaScript sont devenus relativement moins important alors que d’autres comme ceux en charge du formatage, de la mise en page, de la construction des blocs CSS et du rendu sont devenus extrêmement importants.

Cela peut apparaître assez surprenant de prime abord puisque l’on associe naturellement les sites AJAX aux performances du moteur JavaScript. Mais si l’on réfléchit aux modèles de développements utilisés au sein des sites faisant appels aux framework de type AJAX, ces résultats font assez sens. En effet, souvent, des les sites AJAX, vous avez finalement assez peu de code JavaScript. Par ailleurs, ce dernier s’occupe principalement de manipuler le document. Une fois que le script a été exécuté, le navigateur a besoin de passer à travers presque tous les composants pour que cette manipulation soit visible pour l’utilisateur. Or, l’impact généré par le script est généralement plus consommateur que l’exécution du script en lui-même.

On peut donc voir que les performances des sites AJAX sont également liées à des facteurs multidimensionnels et impactées par tous les modules d’un navigateur. Ainsi pour un site AJAX, le composant le plus important semble être celui en charge du rendu responsable de 31% du temps CPU suivi juste derrière par celui en charge du JavaScript consommant de son côté 21% du temps. Il est ainsi intéressant de noter que le moteur JavaScript a proportionnellement plus d’impact lors du chargement d’une page web que lors des interactions avec les sites faisant appels à AJAX.

Synthèse
En conclusion, afin de construire un navigateur rapide pour tous, il faut commencer par comprendre comment chacun de ses modules impacte les performances dans des scénarios réels d’utilisation quotidienne puis il faut se concentrer sur les modules qui apparaissent comme le plus critique. Pour les sites tirant partie des framework de type AJAX, cela implique de se concentrer sur le module de rendu (31%), le moteur JavaScript (21%), le formatage (14%) et la mise en page (12%). Pour les sites d’informations, cela implique de travailler principalement sur le moteur JavaScript (29%), le Marshallling (18%) et sur le moteur de rendu (17%).

Cela vous permettra alors, je l’espère, de mieux comprendre les orientations qui ont guidé nos choix sur la manière de construire les nouvelles fondations de notre prochain navigateur Internet Explorer 9. Nous espérons qu’à travers les analyses que nous avons menées, nous serons en mesure de vous fournir la plateforme la plus rapide pour héberger vos développements. C’est pour cela que nous vous avons parlé au cours des dernières semaines des changements fondamentaux que nous avons introduit à travers une accélération graphique matérielle via le GPU, un JavaScript compilé grâce à Chakra et une intégration native du moteur JavaScript directement au sein du navigateur.  Avec l’arrivée imminente de la Beta d’IE9, vous serez bientôt en mesure de bénéficier de toutes ces innovations et de comparer leurs bénéficies face aux navigateurs de la génération actuelle ne faisant pas appel (ou partiellement) à l’accélération matérielle.

David Rousset
Microsoft France
Article traduit et adapté de l’article de Jason Weber.