Alors si vous êtes intégrateur web et que vous n’avez jamais entendu parler de CSS Houdini, ce qui suit va être un choc. Mais comme nous sommes un 31 octobre quoi de plus naturel de vous faire peur pour Halloween. À l’inverse, si vous en avez déjà entendu parler, vous devez vous demander : qu’est-ce qu’on va bien pouvoir faire avec ça ? Enfin est-ce bien raisonnable d’utiliser cette technologie quand on recherche la web performance ? Quel impact sur le moteur de rendu du navigateur ? On va essayer de vous donner les clefs pour alimenter votre réflexion.
CSS Houdini
Harry Houdini (1874-1926) était un grand illusionniste et cascadeur américano-hongrois, connu surtout pour ses numéros de fuite. De naissance nommé Erich Weisz, il a choisi son nom de scène en référence pour son célèbre prédécesseur français Robert Houdin. Houdini devint célèbre pour ses évasions de menottes, y compris les chaînes et les évasions sous l’eau tout en retenant son souffle.
La CSS Houdini Task Force a donc repris son nom, car son but est de créer une technologie qui permet aux développeurs d’explorer et de comprendre la “magie” derrière les algorithmes de mise en page et de style CSS. Une équipe composée d’ingénieurs de Google, Mozilla, Apple, Microsoft et d’autres constitue le groupe de travail CSS Houdini. Ils travaillent ensemble à la création de projets de spécifications normalisés à terme par le W3C (ce sans quoi on ne vous en parlerais même pas !) .
L’objectif de groupe de travail peux se décrire ainsi :
- permettre aux développeurs web d’étendre les capacités du CSS,
- fournir des API qui permettent de créer des fonctionnalités CSS personnalisées
- et ainsi de modifier le pipeline de rendu du navigateur.
Principe de fonctionnement
Rendu dans le navigateur
Pour comprendre l’intérêt de CSS Houdini, il faut comprendre le fonctionnement du moteur de rendu d’une page web dans un navigateur. Avant d’afficher une page, le navigateur va effectuer les étapes suivantes.
1. Loading / Téléchargement
La récupération du code HTML et CSS. C’est la phase de téléchargement du code initial.
2. Parsing / Analyse
L’analyse du code va permettre l’interprétation de 2 modèles d’objets..
- DOM Document Object Model
HTML est une structure hiérarchique qui commence par une balise <html>, contient généralement une balise <head> et <body>, et les éléments peuvent être imbriqués dans des éléments. Le moteur de rendu analyse ces éléments HTML et les transforme en “arbre DOM”. C’est-à-dire une structure arborescente faite à partir du HTML, où chaque balise est une branche commençant à la racine de l’élément. - CSSOM Style Object Model
Les attributs CSS (attributs de style) sont également analysés. Il s’agit d’une arborescence de propriétés visuelles telles que la hauteur/largeur et la couleur classées selon une hiérarchie de priorité (la cascade de Cascading Style Sheet) que le navigateur doit respecter pour l’affichage des éléments.
3. Render Tree / Arborescence d’affichage
Le DOM et CSSOM sont combinés pour calculer la mise en page de chaque élément visible. Pour cela le navigateur va parcourir tous les éléments du DOM en partant de la racine du document. Il exclut les éléments qui ne sont pas du tout visibles (<script>, <meta>, <head>, etc…) et les éléments explicitement masqués par le code CSS (display: none).
Enfin pour chaque élément, il trouve la règle CSSOM et l’applique.
4. Layout / Mise en page
L’étape précédente a permis de déterminer quels nœuds doivent être visibles et quels styles leurs sont appliqués. Mais leurs positions et leurs tailles exactes dans la fenêtre d’affichage n’ont pas encore été calculées. Pour définir la taille et la position exactes de chaque objet, le navigateur parcours l’arborescence d’affichage. Il calcule ainsi la géométrie et la place de chaque objet dans la page. Au final, le processus de Layout convertit toutes les mesures relatives en positions de pixels absolues sur l’écran.
5. Paint / Peinture
A l’aide des informations calculées par l’étape de Layout, chaque élément est peint pour remplir chaque pixel visible avec des choses comme le fond, les bordures, les ombres et le texte.
Ces éléments sont peints par couches.
6. Composite Layout / Composition des couches
La navigateur prend les différents couches ou calques créés par l’étape Paint et les fusionne dans le bon ordre pour les afficher à l’écran en communiquant avec l’interface du système d’exploitation.
À noter qu’à l’étape 2, si l’analyseur HTML rencontre une balise de script, il suspend la construction du DOM. C’est alors le moteur JavaScript qui prend le relais. Le navigateur reprendra son processus de son moteur de rendu qu’une fois le code javascript terminé. De plus, il faut bien comprendre que les seuls endroits d’intervention pour modifier un affichage interviennent donc au niveau du DOM et CSSOM. Et donc, quand un JavaScript vient modifier le DOM ou CSSDOM, le navigateur doit reprendre toutes les étapes de 2 à 6.
La magie de CSS Houdini
Ainsi la promesse des CSS Houdini, est de rendre accessible toutes les étapes du rendu des pages web dans le navigateur. Ce qui signifie, que nous pourrions produire un code capable d’intervenir à tout moment dans la chaîne de rendu et non plus en bout de chaîne comme avec Javascript. Nous pourrions même contrôler le style et la mise en page avant même que la page ne soit affichée. Bref, il s’agit ni plus ni moins que de modifier le moteur de rendu du navigateur.
Aujourd’hui nous ne pouvons intervenir que sur le DOM et le CSSDOM (cf étape 2). Avec CSS Houdini, le navigateur ouvre la porte des étapes suivantes. Pour cela, l’accès à ces étapes se fait par le biais de diverses API qui exploitent les couches du moteur de rendu du navigateur, auparavant inaccessibles aux développeurs.
Liste des APIs fournies par CSS Houdini
- L’API Layout
ce sont les éléments en display : block, grid ou table qui sont ici concernés, soit de nouvelles manières de positionner et dimensionner nos éléments de mise en page ! - L’API Paint
qui contrôle le dessin des images là où CSS le permet. - L’API Parser
qui donne accès à l’analyseur et aux méthodes du moteur. - L’API Properties and Values
qui contrôle comment les propriétés et les valeurs CSS personnalisées sont comprises. Ainsi, cette API étend le fonctionnement actuel des variables CSS, avec un typage des variables, une valeur par défaut voire même une modification de leur comportement d’héritage. - L’API Animations
qui est une extension de l’API d’animation actuelle et permet d’utiliser l’accélération graphique pour des cadences d’images fluides. En outre, elle permet aussi de lier les animations à des états (comme le défilement) au lieu d’une ligne de temps fixe. - L’API TypedOM
qui organise et structure les valeurs CSS, au lieu d’analyser des chaînes de caractères simples. - et l’API Font Metrics
qui permet certains comportements de polices dans des mises en page personnalisées.
Du JS dans les CSS !
Avant d’aller plus loin, comprenez bien que le code qui utilisent les APIs décrites par CSS Houdini, n’est autre que du JavaScript ! La messe est dite : on a à faire à du JS dans du CSS. Saint Berners Lee, priez pour nous qu’avons nous fait pour mériter une telle infamie !
Avant d’allumer un bûcher, essayons tout de même de comprendre l’implémentation de cette nouvelle hérésie technique.
La nouveauté : les Worklets
Il s’agit de définir des Worklets qui comme les Web Workers, vont travailler sur des threads (fils d’exécution) distincts et donc en parallèle et indépendamment du thread principal. Les Worklets Web sont certes similaires aux Web Workers, mais ils sont plus légers. Ce qu’ils doivent considérer, c’est que dans certains cas, ils doivent être exécutés à chaque rendu par le navigateur. Néanmoins, les Worklets ont une portée beaucoup plus petite, qui est généralement limitée à l’objectif exact du type de Worklet spécifique.
Pour que le navigateur puisse exécuter le code du Worklet, celui-ci est enregistré dans le thread principal JavaScript. Les Worklets sont inclus comme n’importe quel autre JavaScript (via des balises script), mais sont exécutés différemment. Lorsque les Worklets sont exécutés à partir d’une page HTML, ils se chargent de manière asynchrone et ils s’exécutent en arrière-plan, indépendamment des scripts user-ui et du thread principal.
Dès lors, dans les CSS, il suffira d’appeler le Worklet pour déterminer la valeur ou le comportement à attribuer à une propriété. Exemple : border-image-source: paint(tooltip)
. Ici on utilise un Worklet nommé tooltip utilisé pendant l’étape paint.
Ainsi à chaque fois qu’il analyse une propriété CSS qui utilise ce Worklet, le moteur de rendu déclenchera le thread approprié. Le navigateur décide également combien de threads de Worklets sont générés afin d’optimiser les ressources en fonction de leur utilisation.
Pour résumer, la structure pour utiliser CSS Houdini est la suivante :
- un fichier Worklet écrit en JavaScript, léger et dédié à une tache précise,
- une déclaration de ce Worklet dans le thread principal JavaScript,
- un code CSS faisant appel à ce Worklet avec le cas échéant un passage de variables.
Conclusion
Au regard du support actuel, nous avons a faire à une technologie expérimentale. Même avec 63% de part de marché, seules quelques fonctionnalités sont ouvertes dans la dernière version de Chrome et certaines en activant des paramètres avancés. Donc inutile de s’emballer cela ne va pas arriver de suite sur toutes vos pages web. Si vous suivez le blog de notre agence web rennaise, on vous tiendra au courant.
Les exemples
Par contre quand on regarde les exemples fournis sur css-houdini.rocks, c’est quand même bluffant. Parmi les exemples fonctionnels dans Chrome, on remarquera :
- les séparations non rectangulaires,
- les boîtes rugueuses,
- la tooltip simple,
- et surtout la grille irrégulière.
L’avis d’artwaï
Pourtant ce qui se cache derrière cela est encore du JavaScript. Et c’est là que je ne peux que m’inquiéter. Etant donné les dérives actuelles de JavaScript, surtout sa tendance à grossir de plus en plus, je crains fort que le caractère léger des Worklet soit mis à mal.
Toutefois, ouvrir les étapes de rendu a un intérêt certain ! En effet il permet d’intervenir directement au niveau du rendu et non plus à faire nos modifications (issu de calcul souvent complexe en JavaScript) dans le DOM et CSSOM et de relancer toutes les étapes de rendu. Et cela prend tout son sens avec une mise page de type “masonry” par exemple (comme sur street-art-avenue.com). Et en évitant de relancer toutes les étapes de rendu, nous aurons forcément un impact positif sur la web performance.
Tout est donc histoire de discernement ! Si l’objectif de CSS Houdini est de produire des arc-en-ciels en masse sur nos pages web, je sens déjà la migraine poindre. À l’inverse, s’il s’agit d’alléger les étapes du rendu, et d’en profiter pour nettoyer le JavaScript existant de tout ces calculs de rendus gourmand et désormais inutiles, alors là j’applaudirai des deux mains.
Sources : medium.com, synbioz.com, drafts.css-houdini.org, css-houdini.rocks et CSS Houdini Wiki.
Images : commons.wikimedia.org (Master of Mystery, Grim Game et King of Cards)