Les navigateurs avaient passé des années à gagner en fluidité en en faisant moins : invalider uniquement les rectangles modifiés, mettre en cache des éléments sous forme de calques, les composer, puis finalement déplacer ces deux tâches sur le GPU. Sur Mozilla Hacks en octobre 2017, Lin Clark expliquait pourquoi les pages saccadaient encore. Les calques coûtent de la mémoire et du temps de transfert, et les navigateurs doivent deviner combien une page en a besoin. Trop de calques saturent la mémoire et ralentissent le compositeur ; trop peu signifient qu'un calque repeint est composé sans que rien n'ait changé, touchant chaque pixel deux fois. Animer une couleur d'arrière-plan force une repeinture de tout le calque quoi qu'il arrive.
WebRender, technologie de Servo arrivant dans Firefox sous le nom de Quantum Render, suivait un précédent différent : les moteurs de jeu 3D repeignent chaque pixel de chaque image et maintiennent 60 FPS de manière plus fiable que les navigateurs, sur des GPU dotés de centaines ou de milliers de cœurs qui ombrent les pixels en parallèle. WebRender a donc supprimé la frontière peinture/composition. La sortie de la mise en page est devenue une liste d'affichage d'instructions de dessin de haut niveau liées à aucune API graphique. Le RenderBackend de WebRender convertissait cette liste en appels de dessin GPU groupés, et le GPU repeignait toute la scène visible de la page à chaque image, sans deviner les calques.
Rendre abordable le redessin de toute l'image a exigé d'éliminer du travail. Les éléments hors écran étaient éliminés avant d'atteindre le GPU. Un arbre de tâches de rendu planifiait le nombre minimal de textures hors écran coûteuses pour les filtres et les contextes d'empilement. Les appels de dessin étaient groupés pour garder occupés les cœurs parallèles du GPU. Le rendu était divisé en une passe opaque de l'avant vers l'arrière qui sautait les pixels couverts et une passe translucide de l'arrière vers l'avant — l'élimination en z, selon l'article, et un gain important sur les pages typiques. Les glyphes de texte restaient une tâche CPU mais étaient mis en cache dans une texture conservée d'une image à l'autre.
L'objectif était la cohérence, pas seulement la vitesse : pas de falaise de performance, 60 FPS fluides quelle que soit la taille de l'écran ou la portion de la page modifiée. L'article rapportait que des pages qui avançaient péniblement à 15 FPS dans Chrome ou dans le Firefox de l'époque tournaient à 60 FPS avec WebRender, et présentait ce travail comme une préparation aux écrans 4K et à WebVR, qui rend une image pour chaque œil à 90 FPS.
Cesser de deviner les calques : confier au GPU une liste d'affichage de haut niveau et repeindre toute la page à chaque image, à la manière d'un moteur de jeu
Les GPU comptent de centaines à des milliers de cœurs qui ombrent les pixels en parallèle, donc repeindre toute la page visible à chaque image est la charge de travail pour laquelle ils ont été conçus, pas une tâche à l'échelle d'un CPU.
Une liste d'affichage conservée est une description compacte et indépendante de l'API de la scène, donc le CPU construit les commandes une fois et le RenderBackend peut les éliminer, les ordonner et les grouper avant tout travail sur les pixels.
Le redessin de toute la scène supprime la devinette des calques et ses modes de défaillance : pas de nombre de calques mal évalué, pas de double traitement des pixels, donc les temps d'image cessent de chuter au-delà des falaises de performance.
L'élimination du travail garde le redessin abordable : l'élimination, moins de cibles hors écran, le groupement et l'élimination en z réduisent ce que le GPU ombre, tandis que les glyphes rendus par le CPU vivent dans un cache de textures, pas dans le chemin par image.
Quand les heuristiques incrémentales ne cessent de heurter des falaises dans le pire des cas, changez de modèle : décrivez toute la scène une fois et laissez le matériel massivement parallèle la redessiner à chaque image
Suites
WebRender ne faisait pas partie de la version Firefox Quantum qui a suivi : Lin Clark écrivait dans les commentaires de l'article qu'il n'arriverait pas avant Firefox 57, et l'article prévoyait une intégration jusqu'en 2018 dans le cadre du projet Quantum Render, une première version étant déjà disponible derrière un indicateur. La démo à laquelle il renvoyait montrait des pages qui tournaient à 15 FPS dans Chrome ou dans le Firefox de l'époque tournant à 60 FPS avec WebRender, et l'explication a recueilli 853 points et 207 commentaires sur Hacker News le 10 octobre 2017.
VÉRIFIEZ LES SOURCES
Les sources
- The whole web at maximum FPS: How WebRender gets rid of jank Mozilla Hacks · hacks.mozilla.org ·
- Hacker News discussion: The whole web at maximum FPS — How WebRender gets rid of jank Hacker News · news.ycombinator.com ·