Améliorez le temps de chargement initial en ignorant le rendu du contenu hors écran.
Publié le 5 août 2020
La propriété content-visibility
permet à l'agent utilisateur d'ignorer le travail de rendu d'un élément, y compris la mise en page et la peinture, jusqu'à ce qu'il soit nécessaire. Étant donné que l'affichage est ignoré, si une grande partie de votre contenu est hors écran, l'utilisation de la propriété content-visibility
accélère le chargement initial de l'utilisateur. Il permet également d'interagir plus rapidement avec le contenu à l'écran. Plutôt chouette.
Confinement CSS
L'objectif principal et global de la structuration CSS est d'améliorer les performances de rendu du contenu Web en isolant de manière prévisible un sous-arbre DOM du reste de la page.
En gros, un développeur peut indiquer à un navigateur quelles parties de la page sont encapsulées en tant qu'ensemble de contenu, ce qui permet aux navigateurs de raisonner sur le contenu sans avoir à prendre en compte l'état en dehors du sous-arbre. Savoir quels éléments de contenu (sous-arbres) 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 contenu CSS, chacun étant une valeur potentielle pour la propriété CSS contain
, qui peut être combinée dans une liste de valeurs séparées par des espaces:
size
: la structuration de la taille d'un élément garantit que la zone 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 de ne pas avoir à mettre en page les descendants si tout ce que nous voulons faire est de mettre en page d'autres boîtes.style
: le structurant de style garantit que les propriétés qui peuvent avoir des effets sur plus que ses descendants ne s'échappent pas de l'élément (par exemple, les compteurs). Cela nous permet de ne pas calculer le style des descendants si nous ne voulons calculer que des styles sur d'autres éléments.paint
: le confinement de la peinture garantit que les descendants du conteneur ne s'affichent pas en dehors de ses limites. Rien ne peut dépasser visuellement l'élément. Si un élément est hors écran ou autrement invisible, ses descendants ne seront pas non plus visibles. Cela nous permet de ne pas peindre les descendants si l'élément est hors écran.
Ignorer le travail de rendu avec content-visibility
Il peut être difficile de déterminer quelles valeurs de structuration utiliser, car les optimisations du 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 ou utiliser content-visibility
pour appliquer automatiquement le confinement nécessaire. content-visibility
vous permet d'obtenir les meilleurs gains de performances possible avec le navigateur, avec un minimum d'effort de votre part en tant que développeur.
La propriété content-visibility accepte plusieurs valeurs, mais auto
est celle qui offre des améliorations immédiates des performances. Un élément qui possède content-visibility: auto
gagne la structuration layout
, style
et paint
. Si l'élément se trouve en dehors de l'écran (et qu'il n'est pas pertinent pour l'utilisateur, les éléments pertinents sont ceux qui sont ciblés ou sélectionnés dans leur sous-arborescence), il obtient également le confinement de size
(et arrête la peinture et le test de positionnement de son contenu).
Qu'est-ce que cela signifie ? En résumé, si l'élément est hors é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 confinement size
, et commence à peindre le contenu de l'élément et à effectuer un test de positionnement. Cela permet d'effectuer le travail de rendu juste à temps pour être vu par l'utilisateur.
Remarque sur l'accessibilité
L'une des caractéristiques 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 que vous pouvez rechercher du contenu sur la page et y accéder sans attendre qu'il se charge ni sacrifier les performances de rendu.
À l'inverse, les éléments points de repère avec des caractéristiques de style telles 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 éviter qu'ils ne soient visibles dans l'arborescence d'accessibilité, ce qui pourrait encombrer l'arborescence, veillez également à ajouter aria-hidden="true"
.
Exemple : un blog de voyage
Un blog de voyage contient généralement un ensemble d'articles avec quelques photos et du texte descriptif. Voici ce qui se passe dans un navigateur classique lorsqu'il accède à un blog de voyage:
- Une partie de la page est téléchargée à partir du réseau, ainsi que les ressources nécessaires.
- Le navigateur stylise et met en page l'ensemble du contenu de la page, sans tenir compte de la visibilité du contenu pour l'utilisateur.
- Le navigateur revient à l'étape 1 jusqu'à ce que la page et toutes les ressources soient téléchargées.
À l'étape 2, le navigateur traite tous les contenus à la recherche de modifications. Elle met à jour le style et la mise en page des nouveaux éléments, ainsi que ceux qui ont pu changer à la suite de nouvelles mises à jour. Il s'agit d'un rendu. Cette opération prend du temps.
Voyons maintenant ce qui se passe si vous ajoutez content-visibility: auto
à chacune des histoires du blog. La boucle générale est la même : le navigateur télécharge et affiche des parties de la page. Cependant, la différence réside dans la quantité de travail effectuée à l'étape 2.
Avec "content-visibility", il stylise et met en page tous les contenus actuellement visibles par l'utilisateur (ils sont à l'écran). Toutefois, lors du traitement de la story qui est entièrement hors écran, le navigateur ignore le travail de rendu et ne stylise et ne met en page que la zone de l'élément lui-même.
Les performances de chargement de cette page seraient comme si elle contenait des histoires complètes à l'écran et des cases vides pour chacune des histoires hors écran. Les performances sont bien meilleures, avec une réduction attendue de 50% ou plus du coût de rendu du chargement. Dans notre exemple, nous observons une amélioration du temps de rendu de 232 ms à 30 ms. Cela représente une amélioration des performances de 7 fois.
Que devez-vous faire pour profiter de ces avantages ? Tout d'abord, nous découpons le contenu en sections :
Nous appliquons ensuite 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 exploiter les avantages potentiels de content-visibility
, le navigateur doit appliquer la structuration de la taille pour s'assurer que les résultats de rendu des contenus n'affectent en rien la taille de l'élément. Cela signifie que l'élément sera mis en page comme s'il était vide. Si l'élément n'a pas de hauteur spécifiée dans une mise en page de blocs standard, sa hauteur sera de 0.
Ce n'est peut-être pas l'idéal, car la taille de la barre de défilement change, car elle dépend de la hauteur non nulle de chaque histoire.
Heureusement, le CSS fournit une autre propriété, contain-intrinsic-size
, qui spécifie efficacement la taille naturelle de l'élément si l'élément est affecté par la structuration de la taille. Dans notre exemple, nous le définissons sur 1000px
pour estimer la hauteur et la largeur des sections.
Cela signifie qu'il se présentera comme s'il n'avait qu'un seul enfant de dimensions "taille intrinsèque", ce qui garantit que vos divs non dimensionnés occupent toujours de l'espace.
contain-intrinsic-size
sert d'espace réservé à la place du contenu affiché.
Le mot clé auto
pour contain-intrinsic-size
permet au navigateur de mémoriser la taille de rendu la dernière fois, le cas échéant, et de l'utiliser à la place de la taille d'espace réservé fournie par le développeur. Par exemple, si vous avez spécifié contain-intrinsic-size: auto 300px
, l'élément commence avec une taille intrinsèque 300px
dans chaque dimension, mais une fois que le contenu de l'élément est affiché, il conserve la taille intrinsèque affichée.
Toute modification ultérieure de la taille du rendu est également mémorisée. En pratique, cela signifie que si vous faites défiler un élément avec content-visibility: auto
appliqué, puis le faites défiler hors écran, il conservera automatiquement sa largeur et sa hauteur idéales, et ne reviendra pas à la taille 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 de la taille au fil du temps à mesure que l'utilisateur explore la page.
Masquer le contenu avec content-visibility: hidden
Que faire si vous souhaitez conserver le contenu non affiché, que ce soit à l'écran ou non, tout en profitant des avantages de l'état de rendu mis en cache ? Saisissez content-visibility: hidden
.
La propriété content-visibility: hidden
offre tous les avantages du contenu non affiché et de l'état de rendu mis en cache que content-visibility: auto
offre hors écran. Toutefois, contrairement à auto
, l'affichage ne commence pas automatiquement à l'écran.
Vous bénéficiez ainsi d'un contrôle plus précis, ce qui vous permet de masquer le contenu d'un élément et de le réafficher rapidement par la suite.
Comparez ce comportement à 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 le dévoilement 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 sa sous-arborescence) occupe toujours de l'espace géométrique sur la page et l'utilisateur peut toujours cliquer dessus. Il met également à jour l'état de rendu chaque fois qu'il est nécessaire, même lorsqu'il est masqué.
En revanche, content-visibility: hidden
masque l'élément tout en préservant son état de rendu. Par conséquent, si des modifications doivent être effectuées, elles ne se produisent que lorsque l'élément est de nouveau affiché (c'est-à-dire lorsque la propriété content-visibility: hidden
est supprimée).
content-visibility: hidden
est particulièrement utile pour implémenter des défileurs virtuels avancés et mesurer la mise en page. Elles sont également idéales 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 mis en cache. La vue s'affiche ainsi rapidement lorsqu'elle redevient active.
Effets sur l'interaction à la prochaine peinture (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 travail effectuée sur le thread principal, y compris le travail de rendu.
Chaque fois que vous pouvez réduire le travail de rendu sur une page donnée, vous donnez au thread principal la possibilité de répondre plus rapidement aux entrées utilisateur. Cela inclut le travail de rendu. 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 travaux de rendu et de mise en page sont effectués.
La réduction du travail de rendu a un impact 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 le rendu des éléments hors écran, vous donnez au thread principal la possibilité de répondre à un travail critique visible par l'utilisateur. Cela peut améliorer l'INP de votre page dans certains cas.
Conclusion
Avec content-visibility
et la spécification CSS Containment Spec, votre fichier CSS bénéficie directement d'améliorations intéressantes des performances. Pour en savoir plus sur ces propriétés, consultez les ressources suivantes :