34 votes

Comment les CSS sont-elles appliquées par le navigateur, et les repeints en sont-ils affectés ?

Disons que nous avons une page HTML avec une seule feuille de style <link> . Comment le navigateur prend-il les règles de cette feuille de style et les applique-t-il au HTML ? Je ne cherche pas à savoir comment accélérer le processus, je veux savoir comment le rendu lui-même est géré.

Est-ce qu'il applique chaque règle une par une en analysant la feuille de style et en rendant le résultat progressivement ? Ou bien, le contenu du fichier CSS est-il entièrement téléchargé, puis entièrement évalué, et puis appliqué au HTML en une seule fois ? Ou quelque chose d'autre ?

Je pose cette question après avoir posté une réponse plus tôt sur une question sur l'ordre des règles CSS affectant la vitesse de rendu en supposant que les styles ont été rendus. comme le chargement de la feuille de style, ainsi les premières règles seraient appliquées avant les dernières, et non pas toutes en même temps. Je ne sais pas où j'ai trouvé cette idée, c'est juste quelque chose que j'ai toujours pensé.

J'ai essayé une démo sur mon serveur qui ressemblait à ceci :

<!DOCTYPE html>
<html>
<head>
   <title>Test</title>
   <link rel="stylesheet" href="test.css" />
</head>
<body></body>
</html>

test.css le contenu :

html { background:green }
/* thousands of lines of irrelevant CSS to make the download slow */
html { background:red }

Lors du test dans Firefox 5, je m'attendais à voir du vert au début, puis du rouge. Cela ne s'est pas produit. J'ai essayé avec deux feuilles de style distinctes avec des règles contradictoires et j'ai obtenu les mêmes résultats. Après de nombreuses combinaisons, la seule façon d'obtenir un résultat satisfaisant a été d'utiliser une fonction en ligne <style> dans le bloc <head> avec les règles contradictoires provenant d'un <link> dans le <body> (le corps lui-même était complètement vide, à l'exception de la balise de lien). Même en utilisant une balise style de l'attribut <html> et le chargement de cette feuille de style n'a pas créé le scintillement que j'attendais.

Les repeints sont-ils affectés dans tout ou le résultat final est-il appliqué en une seule fois après le téléchargement de la feuille de style entière et le calcul des règles pour obtenir le résultat final ? Les fichiers CSS sont-ils téléchargés en parallèle avec le HTML lui-même ou le bloquent-ils (comme le font les balises script) ? Comment cela fonctionne-t-il réellement ?

Je ne cherche pas des conseils d'optimisation, mais des références faisant autorité sur le sujet, afin de pouvoir les citer à l'avenir. Il a été très difficile de rechercher ces informations sans tomber sur des tonnes de documents sans rapport. Résumé :

  • Tout le contenu du CSS est-il téléchargé avant tout d'elle est appliquée ? (référence s'il vous plaît)
  • Comment cela est-il affecté par des choses comme @import , multiples <link> s, attributs de style en ligne, <style> dans la tête, et différents moteurs de rendu ?
  • Le téléchargement du contenu CSS bloque-t-il le téléchargement du document HTML lui-même ?

0 votes

Un exemple de la raison pour laquelle je m'intéresse à ce sujet : Je crée un fichier CSS miniaturisé à partir de 10 à 15 petits fichiers. Tout est "namespaced", ou utilise des sélecteurs suffisamment spécifiques pour que l'ordre puisse être interverti dans de nombreux cas. J'ai toujours inclus le CSS "moins pertinent" en dernier, en pensant que les styles seraient appliqué en dernier, et que le fait de les faire passer en premier ferait que les éléments plus importants (mise en page ou classes communes par exemple) seraient évalués plus tard. J'ai le sentiment très fort que cela n'est absolument pas pertinent, mais je cherche des faits pour étayer cette affirmation. Une réponse à cette question devrait également répondre à la question liée.

16voto

Matt Ball Points 165937

Comment le navigateur prend-il les règles de cette feuille de style et les applique-t-il au HTML ?

En général, cela se fait en continu. Le navigateur lit les balises HTML comme un flux, et applique les règles qu'il peut aux éléments qu'il a vus jusqu'à présent. (Il s'agit évidemment d'une simplification).

Une question connexe intéressante : Utiliser des sélecteurs CSS pour collecter des éléments HTML à partir d'un analyseur de flux (par exemple, un flux SAX). (une diversion pendant que je cherche l'article que j'ai en tête).


Ah, c'est ici : Pourquoi n'avons-nous pas de sélecteur de parent ? .

Nous pensons souvent que nos pages sont des documents complets, remplis d'éléments et de contenu. Cependant, les navigateurs sont conçus pour traiter les documents comme un flux. Ils commencent à recevoir le document du serveur et peuvent en effectuer le rendu avant qu'il ne soit complètement téléchargé. Chaque nœud est évalué et rendu dans la fenêtre d'affichage au fur et à mesure qu'il est reçu.

Regardez le corps d'un exemple de document :

<body>
   <div id="content">
      <div class="module intro">
         <p>Lorem Ipsum</p>
      </div>
      <div class="module">
         <p>Lorem Ipsum</p>
         <p>Lorem Ipsum</p>
         <p>Lorem Ipsum <span>Test</span></p>
      </div>
   </div>
</body>

Le navigateur commence en haut et voit un body élément. À ce moment-là, il pense que c'est vide. Il n'a rien évalué d'autre. Le navigateur va déterminer quels sont les styles calculés et les appliquer à l'élément et les applique à l'élément Quelle est la police, la couleur, la hauteur de ligne ? Après avoir qu'il a déterminé, il le peint à l'écran.

Ensuite, il voit un div avec un ID de content . Encore une fois, à ce il pense que c'est vide. Il n'a rien évalué d'autre. Le navigateur navigateur calcule les styles et ensuite le div est peint. Le site navigateur déterminera s'il doit repeindre le corps - l'élément a-t-il est-il devenu plus large ou plus haut ? (Je soupçonne qu'il existe d'autres considérations, mais les changements de largeur et de hauteur sont les effets les plus courants que les éléments enfants ont sur leurs parents).

Ce processus se poursuit jusqu'à ce qu'il atteigne la fin du document.

Le CSS est évalué de droite à gauche.

Pour déterminer si une règle CSS s'applique à un élément particulier, il est nécessaire d'utiliser la règle CSS. part de la droite de la règle pour aller vers la gauche.

Si vous avez une règle comme body div#content p { color: #003366; } puis pour chaque élément - au fur et à mesure qu'il est rendu sur la page - il demandera d'abord si c'est un élément de paragraphe. Si c'est le cas, il remontera dans le DOM et et demande si c'est un élément div avec un ID de contenu. S'il trouve ce qu'il cherche il continuera son chemin dans le DOM jusqu'à ce qu'il atteigne l'élément body .

En travaillant de droite à gauche, le navigateur peut déterminer si une règle s'applique à cet élément particulier qu'il tente de peindre dans le fenêtre beaucoup plus rapidement. Pour déterminer quelle règle est plus ou moins plus ou moins performante, vous devez déterminer le nombre de nœuds qui doivent être évalués pour déterminer si un style peut être appliqué à un élément.


Alors pourquoi le contenu de la feuille de style n'a-t-il pas été appliqué progressivement (d'abord le vert, puis le rouge) ?

I pensez à la réponse est que les feuilles de style externes sont analysé au fur et à mesure de leur téléchargement, mais pas appliqué jusqu'à ce que la feuille de style entière ait été analysée. Il est certain qu'en analysant une feuille de style, le navigateur optimise les règles CSS inutiles et redondantes.

Je n'ai pas de preuve à l'appui pour le moment, mais cette explication me semble raisonnable et correspond à ce que vous observez, tant avec les styles externes qu'avec les styles en ligne.

0 votes

Je pense que j'ai un équitable J'ai lu cet article récemment, mais je pense que ce n'est pas le cas. tout à fait ce que je recherche, ou est-ce le cas ? Pourquoi mon test a-t-il échoué ? Le site <html> existait avant l'application de toute CSS, n'est-ce pas ? Alors pourquoi le contenu de la feuille de style n'a-t-il pas été appliqué progressivement (d'abord le vert, puis le rouge) ? J'essaie d'être concis mais je suis plein de questions. Dans mon test, il n'y avait littéralement aucun contenu, à part les balises minimales pour réaliser la démo. Avais-je raison ou tort dans mon autre message ?

0 votes

Voir ma modification (tout en bas de la question). Désolé de taper tout cet article de blog... que vous avez déjà lu. Néanmoins, je pense que c'est important si d'autres ne l'ont pas lu, et j'essaie de faire en sorte que mes réponses soient aussi indépendantes que possible.

0 votes

Non, c'est génial, mec, et il semble que tu sois arrivé à la même conclusion que moi, mais avec des incertitudes. Laisse-moi te poser cette question par curiosité : Avant d'entendre mes résultats, à quoi vous attendiez-vous avec le test que j'ai effectué ? Je reviendrai demain matin pour les votes, les high-fives et autres, j'avais besoin de poser cette question avant d'être absorbé par autre chose, mais ATM m'a épuisé.

9voto

Moses Points 5346

La première chose à comprendre, et la plus importante, est que les navigateurs ne peuvent pas commencer à peindre une page tant que le CSS n'est pas téléchargé. (N'oubliez pas que la spécification du W3C indique que les liens CSS ne sont autorisés que dans l'en-tête, donc lorsque vous commencez à créer des liens vers des feuilles de style dans la balise body comme vous l'avez fait, les différents navigateurs traiteront cette situation différemment).

Désormais, une page Web est lue comme un flux, et les règles CSS sont appliquées aux éléments HTML au fur et à mesure qu'ils sont introduits dans la page. Pour citer l'article de Google dont le lien figure ci-dessous :

Lorsque le navigateur analyse le langage HTML, il construit un arbre de document interne représentant tous les éléments à afficher. Il fait ensuite correspondre les éléments aux styles spécifiés dans diverses feuilles de style, selon les règles standard CSS de cascade, d'héritage et d'ordonnancement.

Je vais maintenant répondre à vos questions :

Applique-t-il chaque règle une par une au fur et à mesure qu'il analyse la feuille de style et rend le résultat progressivement ? Ou bien, le contenu du fichier CSS est-il entièrement téléchargé, puis entièrement évalué, et enfin appliqué au HTML en une seule fois ? Ou quelque chose d'autre ?

Télécharge toutes les CSS, puis commence à peindre le document de haut en bas.

Lors du test dans Firefox 5, je m'attendais à voir du vert au début, puis du rouge. Cela ne s'est pas produit. J'ai essayé avec deux feuilles de style distinctes avec des règles contradictoires et j'ai obtenu les mêmes résultats.

En effet, le CSS est d'abord téléchargé, puis lorsqu'il rencontre votre élément, il n'applique que le style rouge, en raison du fonctionnement de la cascade.

Après de nombreuses combinaisons, la seule façon de le faire fonctionner était un inline <style> dans le bloc <head> avec les règles contradictoires provenant d'un <link> dans le <body>

Bien que je ne puisse pas dire exactement pourquoi cela s'est produit, j'imagine que le navigateur n'a pas cherché le CSS dans la balise body, a commencé à peindre, a rencontré le CSS du corps, puis a repeint.

Les repeints sont-ils affectés de quelque manière que ce soit par le CSS ?

Honnêtement, je m'inquiéterais davantage des repeints causés par JS. Mais si vous avez un très grand DOM, il est logique de structurer votre CSS de telle sorte que vous ne causiez pas de reflux en raison d'un positionnement bizarre. @Matt vous a donné quelques bons liens couvrant ce problème. Quelques bonnes ressources :

http://www.dayofjs.com/videos/22158462/web-browsers_alex-russel Alex Russell explique en détail, au bout de 36 minutes, comment webkit analyse les CSS, comment fonctionnent les reflows et les repaints, et ce qui les déclenche.

http://code.google.com/speed/page-speed/docs/rendering.html Il s'agit d'un article de base sur la façon d'optimiser le rendu des CSS.

0 votes

Vidéo très intéressante, mais je n'ai pas trouvé ce que je cherchais, bien que la section que vous avez mise en évidence explique bien la spécificité des sélecteurs CSS. Pour être clair, je ne demande pas comment accélérer les choses, mais plutôt une explication sur comment/quand les styles CSS sont réellement appliqués, ou comment ils sont transmis au navigateur ou au moteur de rendu à partir d'une feuille de style. Votre réponse : Downloads all CSS, then begins painting the document from the top-down. semble correct, mais je n'arrive pas à trouver de références ou de faits qui confirment ou infirment cela, à part mes propres expériences (probablement imparfaites).

1 votes

@Wesley J'ai en fait répondu à votre question sur comment et quand les styles sont appliqués. Les styles sont appliqués aux éléments du DOM de haut en bas, car le HTML est considéré comme un flux. Plus précisément encore, pour chaque élément que le navigateur voit, il vérifie dans la feuille de style les correspondances CSS potentielles (il lit les CSS à droite et à gauche), puis applique les styles applicables (COMMENT). Ils ne prennent effet que lorsque toutes les CSS sont téléchargées, et c'est à ce moment-là que le navigateur commence à peindre la page (QUAND). Dans mes deux liens, ainsi que dans le lien snook.ca de Matt, les faits présentés confirment cette affirmation.

1 votes

La partie spécifique pour laquelle je cherche une référence est : They do not take effect until all css is downloaded . Est-ce que cela dépend du moteur de rendu, ou est-ce que c'est "juste la façon dont ça fonctionne" ? Dans mon test (qui semble confirmer vos affirmations), <html> était la seule balise avec des règles CSS, et n'a pas été introduite après le téléchargement du CSS, mais avant (à moins que vous ne disiez que la balise de fermeture était nécessaire pour que l'élément soit découvert). Le test a également échoué avec les éléments en ligne style sur la balise html, ce qui était intéressant et inattendu. Je me demande également si le téléchargement de CSS bloque le HTML ou non.

1voto

Assassin Points 80

Je ne suis pas sûr de la réponse marquée. Je doute qu'elle soit correcte. D'après ceci lien depuis Google Developers le navigateur télécharge d'abord le fichier HTML et lorsqu'il voit un fichier CSS lié à une ressource externe, il commence à télécharger le fichier CSS pendant qu'il crée simultanément la structure DOM pour le fichier HTML donné, car le CSS ne va pas affecter le DOM. Notez qu'il n'applique aucun style au document lorsque le navigateur télécharge le fichier CSS.

Après avoir téléchargé le fichier CSS (en supposant qu'il n'y a pas de fichiers script) et si la construction du DOM est terminée, le navigateur commence à faire correspondre les propriétés CSS à ces nœuds dans l'arbre DOM. Après cela, il crée un autre arbre appelé Render tree qui construit tous les objets qui doivent être affichés, comme des boîtes rectangulaires. Ce n'est qu'après avoir complété l'arbre de rendu qu'il commence à peindre sur l'écran.

Pour résumer :

  • Le navigateur télécharge entièrement le fichier CSS.
  • Le navigateur n'applique aucun style à la page lors de son téléchargement. Ce n'est qu'une fois le téléchargement terminé qu'il commence à appliquer les règles.
  • Les règles ne sont appliquées que pendant la phase de construction de l'arbre de rendu.
  • Le téléchargement du fichier CSS ne bloque pas le téléchargement du HTML. Il faut noter que le navigateur

Il télécharge d'abord tous les fichiers html, puis les fichiers de style et de script.

Vous pouvez utiliser la console du développeur de chrome pour les vérifier. Utilisez l'onglet "timeline" pour voir tout cela.

Voici un exemple de l'image de la ligne de temps aquí . Le lien que j'ai posté au début de cette réponse explique tout.

0 votes

Jetez également un coup d'œil à ce site web. html5rocks.com/fr/tutorials/internals/howbrowserswork

0 votes

Je pense que l'OP a demandé comment les styles css seront appliqués et non l'ordre de rendu d'une page html.

0 votes

Il serait impossible pour CSS de bloquer le HTML déjà demandé. télécharger - la question est de savoir si l'analyse/rendu est bloqué. Et notez : la doc que vous mettez en lien dit que la séquence que vous résumez est une simplification - beaucoup de choses se passent en parallèle : "Pour une meilleure expérience utilisateur, le moteur de rendu essaiera d'afficher le contenu à l'écran le plus rapidement possible. Il n'attendra pas que tout le HTML soit analysé pour commencer à construire et à disposer l'arbre de rendu. Des parties du contenu seront analysées et affichées, tandis que le processus se poursuit avec le reste du contenu qui continue à arriver du réseau."

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X