Booster les performances avec contain en CSS (Containment Module)

Mathieu Chartier Développement 4 commentaires

CSS ne cesse de progresser et de proposer des nouveautés fortement intéressantes. À l'heure où la performance des pages est importante pour l'UX Design et les utilisateurs, le module CSS Containment devrait plaire aux intégrateurs et développeurs front à coup sûr. Avec un bon usage de la propriété contain, la gestion des performances internes des pages devrait nettement s'améliorer. Comble de chance, le CSS Containement module fait partie de la recommandation du W3C, il ne reste qu'à attendre une pleine compatibilité dans l'ensemble des navigateurs (Internet Explorer, Microsoft Edge et Apple Safari ne sont pas encore compatibles).

À quoi sert contain en CSS ?

La propriété CSS contain permet de modifier la portée (scope) d'un noeud dans l'arbre DOM. Autrement dit, contain a pour vocation de rendre indépendants les blocs et leurs contenus du reste de l'arbre du document. L'objectif de la propriété est d'offrir de meilleures performances globales en ne faisant recalculer au navigateur que les positions, la mise en forme, les dispositions et l'affichage des éléments ciblés plutôt que le document complet.

Dans un fonctionnement classique, l'arbre DOM est recalculé entièrement lorsque l'on affecte un noeud de la page, ce qui engendre des calculs plus lourds et coûteux en performance. Avec la propriété contain, ces calculs sont réduits à leur strict minimum en se focalisant uniquement sur le ou les noeud(s) concerné(s), sans affecter le reste de l'arbre DOM.

Si vous créez des pages simples, avec une architecture plutôt simple, l'intérêt de la propriété contain est limité. En revanche, si vous possédez un site avec un arbre structurel complexe ou avec l'usage de widgets externes (par exemple des widgets de réseaux sociaux, etc.), la propriété CSS prend tout son sens. Son usage peut aussi être intéressant pour les noeuds situés hors écran, à l'instar du lazy loading. L'idée est d'isoler des blocs du document pour booster leurs performances, mais cela demande une certaine application.

Comment utiliser contain en CSS ?

La documentation de Mozilla vous fournit l'ensemble des valeurs disponibles pour la propriété CSS contain, tout comme la documentation de Google qui montre un exemple de gain de performances. Il ne reste qu'à chacun de les utiliser à bon escient, je n n'évoquerai ici que quelques cas spécifiques. Malgré tout, voici les listes des valeurs disponibles : none (par défaut), strict, content, size, layout, style, paint ou encore les valeurs globales inherit, initial et unset.

Propriété CSS contain du module CSS containment (recommandation W3C)

La valeur la plus intéressante en termes de performances est généralement "layout". Elle permet de rendre totalement indépendant le noeud et son contenu du reste du document. Rien ne peut affecter sa disposition interne et vice versa. Habituellement, la mise en page (layout) impacte l'ensemble de l'arbre DOM. Avec contain:layout, le navigateur ne calcule le comportement des éléments internes (descendants) que s'ils sont modifiés, et le reste du DOM n'est pas affecté. Dans de nombreux cas, les performances sont nettement accrues.

La valeur "paint" est très intéressante pour gérer les blocs hors écran. En effet, elle permet d'indiquer à l'élément et ses descendants de ne pas s'afficher en dehors de ses limites. En d'autres termes, contain:paint agit un peu d'un overflow:hidden nouvelle génération. Ici, l'intérêt est de ne faire calculer au navigateur que les éléments visibles afin d'améliorer les performances globales. Notez toutefois que la valeur "paint" a des effets secondaires, notamment avec les propriétés position et z-index.

La valeur contain:size garantit que l'élément conteneur pourra être dimensionné sans avoir à vérifier ses noeuds descendants. De son côté, contain:style permet de confiner les propriétés des descendants uniquement au conteneur, et pas à d'autres éléments qui auraient pu aussi les appliquer. Ici, l'objectif est clairement de limiter la portée des styles uniquement aux éléments spécifiés, et pas aux autres noeuds qui auraient pu appliquer les mêmes styles...

Enfin, il existe des meta-valeurs qui regroupent celles que nous venons de voir. contain:content revient à cumuler les valeurs layout et paint, tandis que contain:strict regroupe layout, paint et size.

Retenons deux cas intéressants en termes de performances :

  • La gestion des contenus hors écran avec contain:paint. Ainsi, les éléments éloignés de l'écran visible ne sont pas chargés inutilement (il faudra tout de même penser à charger les éléments au fur et à mesure, etc.).
  • La gestion de widgets tiers, sur lequel nous avons peu de pouvoir, avec contain:strict. Ainsi, les codes tiers n'affectent pas le reste de l'arbre DOM, qui peut se charger "normalement". Il faut bien avouer que de nombreux sites font appel à des widgets/blocs externalisés qui peuvent nettement ralentir le chargement de l'arbre DOM originel...

Comme CSS Containment fait désormais partie de la recommandation W3C, il ne reste qu'à patienter pour que tous les navigateurs l'intègrent (c'est en cours pour Microsoft Edge par exemple). Il s'agit d'une excellente nouvelle qui devrait ravir les fans d'optimisation des performances, et qui devrait aider à améliorer le confort des utilisateurs et l'efficience des pages...