content-Visibility: la nouvelle propriété CSS qui améliore les performances d'affichage

Améliorez le temps de chargement initial en ignorant l'affichage du contenu hors écran.

La propriété content-visibility, lancée dans Chromium 85, pourrait être l'une des nouvelles propriétés CSS les plus efficaces pour améliorer les performances de chargement des pages. content-visibility permet à l'user-agent d'ignorer le travail de rendu d'un élément, y compris la mise en page et la peinture, jusqu'à ce que cela soit nécessaire. Comme l'affichage est ignoré, si une grande partie de votre contenu se trouve en dehors de l'écran, l'utilisation de la propriété content-visibility accélère considérablement le chargement initial de l'utilisateur. Cela permet également d'interagir plus rapidement avec le contenu à l'écran. Génial.

Démonstration avec des figures représentant les résultats du réseau
Dans notre démonstration d'article, l'application de content-visibility: auto à des zones de contenu fragmentées permet d'améliorer les performances d'affichage sept fois lors du chargement initial. Lisez la suite pour en savoir plus.

Prise en charge des navigateurs

Navigateurs pris en charge

  • 85
  • 85
  • 124

Source

content-visibility s'appuie sur des primitives contenues dans la spécification de confinement CSS. Bien que content-visibility n'est compatible qu'avec Chromium 85 pour le moment (et considéré comme "prototypage de valeur pour Firefox), la spécification de confinement est prise en charge par la plupart des navigateurs récents.

Structuration CSS

L'objectif principal de la structuration CSS est de permettre d'améliorer les performances d'affichage du contenu Web en offrant une isolation prévisible d'une sous-arborescence DOM du reste de la page.

En fait, un développeur peut indiquer à un navigateur quelles parties de la page sont encapsulées sous la forme d'un ensemble de contenu, ce qui permet aux navigateurs de réfléchir au contenu sans avoir à tenir compte de l'état en dehors de la sous-arborescence. Savoir quels bits de contenu (sous-arborescences) contiennent du contenu isolé permet au navigateur de prendre des décisions d'optimisation pour le rendu de la page.

Il existe quatre types de confinement CSS, chacun correspondant à une valeur potentielle pour la propriété CSS contain, qui peut être combiné dans une liste de valeurs séparées par des espaces:

  • size: le confinement de la taille d'un élément garantit que la boîte de l'élément peut être mise en page sans avoir à examiner ses descendants. Cela signifie que nous pouvons potentiellement ignorer la mise en page des descendants si nous n'avons besoin que de la taille de l'élément.
  • layout: le confinement de la mise en page signifie que les descendants n'affectent pas la mise en page externe des autres zones de la page. Cela nous permet d'ignorer la mise en page des descendants si tout ce que nous voulons faire est de disposer d'autres cases.
  • style: le confinement des styles garantit que les propriétés qui peuvent avoir des effets sur plus que ses descendants n'échappent pas à l'élément (par exemple, les compteurs). Cela nous permet d'ignorer le calcul de style pour les descendants si nous ne voulons que calculer des styles sur d'autres éléments.
  • paint: le conteneur de peinture garantit que les descendants de la zone conteneurisée ne s'affichent pas en dehors de ses limites. Rien ne peut dépasser visiblement l'élément. Par ailleurs, si un élément se trouve en dehors de l'écran ou n'est pas visible, ses descendants ne le seront pas non plus. Cela nous permet d'éviter de peindre les descendants si l'élément se trouve hors de l'écran.

Ignorer l'opération de rendu avec content-visibility

Il peut être difficile de déterminer quelles valeurs de structuration utiliser, car les optimisations de navigateur ne peuvent se déclencher que lorsqu'un ensemble approprié est spécifié. Vous pouvez tester les valeurs pour voir ce qui fonctionne le mieux. Vous pouvez également utiliser une autre propriété CSS appelée content-visibility pour appliquer automatiquement le confinement nécessaire. content-visibility vous permet d'obtenir les meilleurs gains de performances que le navigateur ne vous permet de fournir qu'un minimum d'efforts de votre part en tant que développeur.

La propriété de visibilité du contenu accepte plusieurs valeurs, mais auto est celle qui permet d'améliorer immédiatement les performances. Un élément qui possède content-visibility: auto acquiert le confinement layout, style et paint. Si l'élément se trouve hors de l'écran (et qu'il n'est pas pertinent pour l'utilisateur, car les éléments pertinents sont ceux qui sont ciblés ou sélectionnés dans leur sous-arborescence), il obtient également le confinement size (et arrête le peinture et le test de positionnement de son contenu).

Qu'est-ce que cela signifie ? En bref, si l'élément se trouve en dehors de l'écran, ses descendants ne sont pas affichés. Le navigateur détermine la taille de l'élément sans tenir compte de son contenu, et s'arrête là. La plupart du rendu, comme le style et la mise en page de la sous-arborescence de l'élément, sont ignorés.

Lorsque l'élément s'approche de la fenêtre d'affichage, le navigateur n'ajoute plus le conteneur size et commence à peindre et à tester le contenu de l'élément. Ainsi, le travail de rendu peut être effectué juste à temps pour être vu par l'utilisateur.

Remarque sur l'accessibilité

L'une des fonctionnalités de content-visibility: auto est que le contenu hors écran reste disponible dans le modèle d'objet de document, et donc dans l'arborescence d'accessibilité (contrairement à visibility: hidden). Cela signifie qu'il est possible de rechercher ce contenu sur la page et d'y accéder sans attendre le chargement ni compromettre les performances d'affichage.

Toutefois, l'inverse est que les éléments repères avec des éléments géographiques de style tels que display: none ou visibility: hidden apparaissent également dans l'arborescence d'accessibilité lorsqu'ils sont hors écran, car le navigateur n'affiche pas ces styles tant qu'ils n'entrent pas dans la fenêtre d'affichage. Pour les empêcher d'être visibles dans l'arborescence d'accessibilité, ce qui pourrait encombrer l'espace, veillez également à ajouter aria-hidden="true".

Exemple: blog de voyage

Dans cet exemple, nous utilisons la référence de notre blog de voyages sur la droite et nous appliquons content-visibility: auto aux sections de section sur la gauche. Les résultats montrent un délai d'affichage allant de 232 ms à 30 ms lors du chargement initial de la page.

Un blog de voyage contient généralement un ensemble d'histoires avec quelques images et un texte descriptif. Voici ce qui se passe dans un navigateur classique lorsque l'utilisateur accède à un blog de voyage:

  1. Une partie de la page est téléchargée à partir du réseau, avec toutes les ressources nécessaires.
  2. Le navigateur définit et affiche l'ensemble du contenu de la page, sans tenir compte de sa visibilité.
  3. Le navigateur revient à l'étape 1 jusqu'à ce que la page et les ressources soient toutes téléchargées.

À l'étape 2, le navigateur traite l'ensemble des contenus à la recherche d'éléments susceptibles d'avoir changé. Elle met à jour le style et la mise en page des nouveaux éléments, ainsi que des éléments qui ont pu changer à la suite des nouvelles mises à jour. Il s'agit du rendu du travail. Cela prend du temps.

Capture d'écran d'un blog de voyage
Exemple de blog de voyage Voir la démonstration sur Codepen

Voyons maintenant ce qui se passe si vous ajoutez content-visibility: auto à chacune des histoires individuelles du blog. La boucle générale est la même: le navigateur télécharge et affiche des fragments de la page. Cependant, la différence réside dans la quantité de travail effectuée à l'étape 2.

La visibilité du contenu permet d'appliquer un style et une mise en page à l'ensemble du contenu actuellement visible par l'utilisateur (il s'affiche à l'écran). Toutefois, lors du traitement de l'histoire entièrement hors écran, le navigateur ignore le travail de rendu et se contente de styliser et de mettre en page la zone de l'élément elle-même.

Le chargement de cette page s'effectue comme si elle contenait des articles en plein écran et des zones vides pour chacun des articles hors écran. Cela offre de bien meilleures performances, avec une réduction attendue de 50% ou plus du coût de rendu du chargement. Dans notre exemple, le délai d'affichage est passé d'un délai de 232 ms à un délai d'affichage de 30 ms. Les performances sont multipliées par sept.

Que devez-vous faire pour en profiter ? Tout d'abord, nous allons diviser le contenu en sections:

Capture d'écran annotée de la segmentation du contenu en sections avec une classe CSS.
Exemple de segmentation de contenu en sections avec la classe story appliquée pour recevoir content-visibility: auto. Voir la démonstration sur Codepen

Ensuite, nous appliquons la règle de style suivante aux sections:

.story {
  content-visibility: auto;
  contain-intrinsic-size: 1000px; /* Explained in the next section. */
}

Spécifier la taille naturelle d'un élément avec contain-intrinsic-size

Pour profiter des avantages potentiels de content-visibility, le navigateur doit appliquer le confinement de la taille pour s'assurer que les résultats d'affichage du contenu n'affectent en aucune façon la taille de l'élément. Cela signifie que l'élément s'affichera comme s'il était vide. Si la hauteur de l'élément n'est pas spécifiée dans une mise en page de blocs standard, sa hauteur sera de 0.

Ce n'est peut-être pas idéal, car la taille de la barre de défilement sera décalée, car la hauteur de chaque histoire sera différente de zéro.

Heureusement, le CSS fournit une autre propriété, contain-intrinsic-size, qui spécifie de manière efficace la taille naturelle de l'élément si celui-ci est affecté par le confinement de la taille. Dans notre exemple, nous la définissons sur 1000px comme estimation de la hauteur et de la largeur des sections.

Ainsi, les éléments div sont affichés comme s'ils n'avaient qu'un seul enfant de dimensions de "taille intrinsèque", ce qui permet de s'assurer que les éléments div non dimensionnés occupent toujours de l'espace. contain-intrinsic-size sert de taille d'espace réservé au lieu du contenu affiché.

Dans Chromium 98 et les versions ultérieures, il existe un nouveau mot clé auto pour contain-intrinsic-size. Si cette option est spécifiée, le navigateur mémorise la dernière taille affichée, le cas échéant, et l'utilise à la place de la taille de l'espace réservé fournie par le développeur. Par exemple, si vous avez spécifié contain-intrinsic-size: auto 300px, l'élément commencera avec une dimensionnement intrinsèque 300px dans chaque dimension, mais une fois le contenu de l'élément affiché, il conservera sa taille intrinsèque. Toute modification ultérieure de la taille de rendu sera également mémorisée. En pratique, cela signifie que si vous faites défiler un élément avec content-visibility: auto appliqué, puis que vous le faites défiler hors de l'écran, il conserve automatiquement sa largeur et sa hauteur idéales et ne revient pas au dimensionnement de l'espace réservé. Cette fonctionnalité est particulièrement utile pour les défilements infinis, qui peuvent désormais améliorer automatiquement l'estimation du dimensionnement au fil du temps, à mesure que l'utilisateur explore la page.

Masquage du contenu avec content-visibility: hidden

Comment faire si vous souhaitez que le contenu ne s'affiche pas, qu'il s'affiche ou non à l'écran, tout en profitant des avantages de l'état d'affichage mis en cache ? Saisissez content-visibility: hidden.

La propriété content-visibility: hidden vous offre les mêmes avantages du contenu non affiché et de l'état de rendu mis en cache que content-visibility: auto en dehors de l'écran. Toutefois, contrairement à auto, l'affichage ne commence pas automatiquement à l'écran.

Vous bénéficiez ainsi d'un contrôle accru, ce qui vous permet de masquer le contenu d'un élément et de l'afficher rapidement par la suite.

Comparez-la à d'autres méthodes courantes pour masquer le contenu d'un élément:

  • display: none: masque l'élément et détruit son état de rendu. Cela signifie que l'affichage de l'élément est aussi coûteux que l'affichage d'un nouvel élément avec le même contenu.
  • visibility: hidden: masque l'élément et conserve son état de rendu. Cela ne supprime pas vraiment l'élément du document, car il (et son sous-arborescence) occupe toujours un espace géométrique sur la page et il est toujours possible de cliquer dessus. Il met également à jour l'état de rendu à chaque fois que cela est nécessaire, même s'il est masqué.

En revanche, content-visibility: hidden masque l'élément tout en conservant son état de rendu. Par conséquent, si des modifications doivent se produire, elles ne se produisent que lorsque l'élément est affiché à nouveau (c'est-à-dire que la propriété content-visibility: hidden est supprimée).

content-visibility: hidden est très utilisé pour implémenter des défilements virtuels avancés et mesurer la mise en page. Ils sont également parfaits pour les applications monopages (SPA). Les vues d'application inactives peuvent être laissées dans le DOM avec content-visibility: hidden appliqué pour empêcher leur affichage, mais conserver leur état de mise en cache. Ainsi, la vue s'affiche rapidement lorsqu'elle redevient active.

Effets sur l'interaction to Next Paint (INP)

INP est une métrique qui évalue la capacité d'une page à répondre de manière fiable aux entrées utilisateur. La réactivité peut être affectée par toute quantité excessive de tâches effectuées sur le thread principal, y compris le travail d'affichage.

Chaque fois que vous pouvez réduire le travail de rendu sur une page donnée, vous donnez au thread principal l'opportunité de répondre plus rapidement aux entrées utilisateur. Cela inclut le travail de rendu, et l'utilisation de la propriété CSS content-visiblity le cas échéant peut réduire le travail de rendu, en particulier au démarrage, lorsque la plupart des tâches de rendu et de mise en page sont terminées.

La réduction du travail de rendu a un effet direct sur l'INP. Lorsque les utilisateurs tentent d'interagir avec une page qui utilise correctement la propriété content-visibility pour différer la mise en page et l'affichage des éléments hors écran, vous donnez au thread principal l'occasion de répondre aux tâches essentielles visibles par l'utilisateur. Cela peut améliorer l'INP de votre page dans certains cas.

Conclusion

content-visibility et la spécification de confinement CSS signifient que votre fichier CSS sera directement amélioré. Pour en savoir plus sur ces propriétés, consultez les pages suivantes: