34 Stimmen

Wie wendet der Browser CSS an, und werden Repaints davon beeinflusst?

Sagen wir, wir haben eine HTML-Seite mit einem einzigen Stylesheet . Wie übernimmt der Browser die Regeln in diesem Stylesheet und wendet sie auf das HTML an? Ich frage nicht, wie man es schneller machen kann, ich möchte wissen, wie das Rendering selbst gehandhabt wird.

Wendet es jede Regel nacheinander an, während es das Stylesheet analysiert und das Ergebnis progressiv rendert? Oder werden die Inhalte der CSS-Datei vollständig heruntergeladen, dann vollständig ausgewertet und dann auf das HTML auf einmal angewendet? Oder etwas anderes?

Ich frage das, nachdem ich früher eine Antwort auf eine Frage über die Reihenfolge der CSS-Regeln, die die Rendering-Geschwindigkeit beeinflussen gepostet habe, unter der Annahme, dass die Styles während das Stylesheet geladen wurde, angewendet wurden, so dass die ersten Regeln angewendet würden, bevor die letzten, und nicht alle auf einmal. Ich bin mir nicht sicher, woher ich die Idee habe, es ist einfach etwas, was ich immer gedacht habe.

Ich habe ein Demobeispiel auf meinem Server ausprobiert, das so aussah:

   Test

test.css Inhalt:

html { background:green }
/* Tausende von Zeilen irrelevanter CSS, um den Download langsam zu machen */
html { background:red }

Beim Testen in Firefox 5 erwartete ich zuerst grün zu sehen, dann zu rot zu wechseln. Das ist nicht passiert. Ich habe es mit zwei separaten Stylesheets mit widersprüchlichen Regeln versucht und die gleichen Ergebnisse erhalten. Nach vielen Kombinationen war der einzige Weg, wie ich es zum Laufen gebracht habe, ein Inline-</code> Block im <code><head></code>, wobei die widersprüchlichen Regeln von einem <code><link></code> im <code><body></code> kamen (der <body> selbst war vollständig leer außer dem Link-Tag). Auch bei Verwendung eines Inline-<code>style</code>-Attributs am <code><html></code>-Tag und dann Laden dieses Stylesheets wurde der Blinker, den ich erwartet hatte, nicht erzeugt.</p> <p>Werden Nachmalungen in <em>irgendeiner</em> Weise durch das CSS beeinflusst, oder wird das Endergebnis erst angewendet, nachdem das gesamte Stylesheet heruntergeladen und seine Regeln berechnet wurden, wie das Endergebnis sein sollte? Werden CSS-Dateien parallel mit dem HTML selbst heruntergeladen oder blockieren sie es (wie Skript-Tags)? Wie funktioniert das eigentlich?</p> <p>Ich suche keine Optimierungstipps, sondern nach autoritativen Referenzen zu diesem Thema, damit ich sie in Zukunft zitieren kann. Es war sehr schwierig, diese Informationen zu suchen, ohne tonnenweise nicht zusammenhängendes Material zu finden. Zusammenfassung:</p> <ul> <li>Wird der gesamte CSS-Inhalt heruntergeladen, bevor <em>irgendetwas</em> davon angewendet wird? (Bitte Referenz)</li> <li>Wie wird dies von Dingen wie <code>@import</code>, mehreren <code><link></code>, Inline-Style-Attributen, <code><style></code>-Blöcken im Kopf und verschiedenen Rendering-Engines beeinflusst?</li> <li>Blockiert der Download von CSS-Inhalten den Download des HTML-Dokuments selbst?</li> </ul></x-turndown>

0 Stimmen

Ein Beispiel dafür, warum mir das wichtig ist: Ich erstelle eine minimierte CSS-Datei aus 10-15 kleinen Dateien. Alles ist "namespaced" oder verwendet spezifische Selektoren, bei denen die Reihenfolge in vielen Fällen vertauscht werden kann. Ich habe immer das "weniger relevante" CSS zuletzt eingefügt, in der Annahme, dass die Stile zuletzt angewendet werden und dass sie zuerst stehen würden, damit das wichtigere Zeug (Seitenlayout oder gemeinsame Klassen zum Beispiel) später ausgewertet werden. Ich habe sehr starke Gefühle, dass dies völlig irrelevant ist, suche aber nach Fakten, die das unterstützen. Eine Antwort darauf sollte auch die verlinkte Frage beantworten.

16voto

Matt Ball Punkte 343109

Wie wendet der Browser die Regeln dieses Stylesheets auf das HTML an?

Typischerweise geschieht dies im Streaming-Stil. Der Browser liest die HTML-Tags als Stream und wendet die Regeln auf die Elemente an, die er bisher gesehen hat. (Das ist natürlich eine Vereinfachung.)

Ein interessantes verwandtes Frage-Antwort-Spiel: Verwenden von CSS-Selektoren zum Sammeln von HTML-Elementen aus einem Streaming-Parser (z.B. SAX-Stream) (eine Ablenkung, während ich nach dem Artikel suche, den ich im Kopf habe).


Ah, hier ist es: Warum wir keinen Eltern-Selektor haben.

Wir denken oft an unsere Seiten als diese vollständigen und vollständigen Dokumente voller Elemente und Inhalte. Browser sind jedoch darauf ausgelegt, Dokumente wie einen Strom zu behandeln. Sie beginnen, das Dokument vom Server zu empfangen und können das Dokument rendern, bevor es vollständig heruntergeladen wurde. Jeder Knoten wird bewertet und auf dem Bildschirm angezeigt, sobald er empfangen wird.

Werfen Sie einen Blick auf den Body eines Beispieldokuments:

         Lorem Ipsum

         Lorem Ipsum
         Lorem Ipsum
         Lorem Ipsum Test

Der Browser beginnt oben und sieht ein body-Element. Zu diesem Zeitpunkt denkt er, er sei leer. Er hat noch nichts anderes bewertet. Der Browser wird bestimmen, was die berechneten Styles sind und wendet sie auf das Element an. Was ist die Schriftart, die Farbe, die Zeilenhöhe? Nachdem er das herausgefunden hat, malt er es auf den Bildschirm.

Als nächstes sieht er ein div-Element mit einer ID von content. Wiederum zu diesem Zeitpunkt denkt er, er sei leer. Er hat noch nichts anderes bewertet. Der Browser findet die Styles heraus und dann wird das div gemalt. Der Browser wird bestimmen, ob er den Body neu malen muss - wurde das Element breiter oder höher? (Ich vermute, es gibt andere Überlegungen, aber Breite- und Höhenänderungen sind die häufigsten Auswirkungen, die Kinderelemente auf ihre Eltern haben.)

Dieser Prozess setzt sich fort, bis er das Ende des Dokuments erreicht hat.

CSS wird von rechts nach links ausgewertet.

Um festzustellen, ob eine CSS-Regel auf ein bestimmtes Element zutrifft, beginnt es bei der rechten Seite der Regel und arbeitet sich von rechts nach links.

Wenn Sie eine Regel wie body div#content p { color: #003366; } haben, dann für jedes Element - während es auf die Seite gerendert wird - wird es zunächst prüfen, ob es ein Absatzelement ist. Wenn ja, wird es sich den DOM hinaufarbeiten und prüfen, ob es ein div mit einer ID von content ist. Wenn es findet, wonach es sucht, wird es den DOM entlang weiterarbeiten, bis es den body erreicht.

Indem es von rechts nach links arbeitet, kann der Browser viel schneller feststellen, ob eine Regel auf ein bestimmtes Element, das er auf den Bildschirm malen möchte, angewendet werden kann. Um festzustellen, welche Regel performanter ist, müssen Sie herausfinden, wie viele Knoten evaluiert werden müssen, um festzustellen, ob einem Element ein Style angewendet werden kann.


Warum wurde der Inhalt des Stylesheets nicht progressiv angewendet (zuerst grün, dann rot)?

Ich denke, die Antwort ist, dass externe Stylesheets während des Downloads geparsen, aber nicht angewendet werden, bis das gesamte Stylesheet geparst wurde. Sicherlich optimiert der Browser beim Pausen eines Stylesheets unnötige und redundante CSS-Regeln.

Ich habe derzeit keinen Beweis dafür, aber diese Erklärung klingt für mich vernünftig und stimmt mit dem überein, was du siehst, sowohl bei externen als auch internen Styles.

0 Stimmen

Ich glaube, ich habe ein gutes Verständnis dafür, wie Neuzeichnungen von neuem HTML beeinflusst werden, das an den Browser gesendet wird, und ich habe diesen Artikel kürzlich gelesen, aber ich glaube, das ist nicht ganz, wonach ich suche, oder? Warum ist mein Test fehlgeschlagen? Das -Tag existierte, bevor irgendein CSS angewendet wurde, nicht wahr? Warum wurde der Stylesheet-Inhalt nicht progressiv angewendet (zuerst grün, dann rot)? Ich versuche präzise zu sein, aber ich habe viele Fragen. In meinem Test gab es buchstäblich keinen Inhalt außer den minimalen Tags, die für die Demo benötigt wurden. Habe ich Recht oder Unrecht in meinem anderen Beitrag?

0 Stimmen

Siehe meine Bearbeitung (ganz unten in der Frage). Entschuldigung, dass ich den ganzen Blog-Beitrag reingeworfen habe... den du bereits gelesen hast. Trotzdem denke ich, dass er relevant ist, wenn andere ihn nicht gelesen haben, und ich versuche wirklich, meine Antworten so selbsterklärend wie möglich zu gestalten.

0 Stimmen

Nein, das ist großartiges Zeug, Mann, und es scheint, dass du zu dem gleichen Schluss gekommen bist wie ich, aber mit Unsicherheit. Lass mich dich das aus Neugier fragen: Bevor du meine Ergebnisse gehört hast, was hättest du erwartet, dass mit dem Test passiert, den ich durchgeführt habe? Ich komme morgen für Abstimmungen und High Fives und so weiter zurück, ich musste diese Frage noch schnell stellen, bevor ich von etwas anderem in Beschlag genommen werde, aber im Moment bin ich erschöpft.

9voto

Moses Punkte 8923

Das erste und wichtigste Verständnis ist, dass Browser nicht mit dem Malen einer Seite beginnen können, bis alle CSS heruntergeladen ist. (Denken Sie daran, dass die W3C-Spezifikation besagt, dass CSS-Links nur im Head erlaubt sind, daher werden verschiedene Browser diese Situation unterschiedlich behandeln, wenn Sie wie Sie Stylesheets im Body-Tag verlinken.)

Jetzt wird eine Webseite als Stream gelesen und CSS-Regeln werden auf HTML-Elemente angewendet, während sie in die Seite eingespeist werden. Um den unten verlinkten Google-Artikel zu zitieren:

Wenn der Browser HTML analysiert, erstellt er einen internen Dokumentenbaum, der alle anzuzeigenden Elemente darstellt. Dann werden Elemente den in verschiedenen Stylesheets angegebenen Stilen entsprechend den Standard-CSS-Kaskade-, Vererbungs- und Reihenfolgeregeln zugeordnet.

Also, um nun Ihre Fragen zu beantworten:

Wendet er jede Regel nacheinander an, während er das Stylesheet analysiert, und rendert das Ergebnis progressiv? Oder werden die Inhalte der CSS-Datei vollständig heruntergeladen, dann vollständig ausgewertet und dann gleichzeitig auf das HTML angewendet? Oder etwas anderes?

Lädt zuerst alle CSS herunter und beginnt dann mit dem Malen des Dokuments von oben nach unten.

Beim Testen in Firefox 5 erwartete ich zuerst Grün zu sehen, das dann zu Rot wird. Das ist nicht passiert. Ich habe es mit zwei separaten Stylesheets mit konkurrierenden Regeln versucht und dieselben Ergebnisse erhalten.

Dies liegt daran, dass das CSS zuerst vollständig heruntergeladen wird und dann, als es auf Ihr Element stieß, nur den roten Stil angewendet hat, basierend darauf, wie die Kaskade funktioniert.

Nach vielen Kombinationen gelang es mir nur mit einem Inline-</code>-Block im <code><head></code>, wobei die konkurrierenden Regeln von einem <code><link></code> im <code><body></code> kamen.</p> </blockquote> <p>Obwohl ich nicht genau sagen kann, warum das passiert ist, stelle ich mir vor, dass der Browser nicht nach CSS im Body-Tag gesucht hat, mit dem Malen begonnen hat, auf das Body-CSS gestoßen ist und dann neu gemalt hat.</p> <blockquote> <p>Wird das Neumalen auf irgendeine Weise vom CSS beeinflusst?</p> </blockquote> <p>Ich wäre ehrlich gesagt mehr besorgt über JS-verursachte Neumalereien. Aber wenn Sie ein sehr großes DOM haben, macht es Sinn, Ihr CSS so zu strukturieren, dass Sie keine Reflows aufgrund merkwürdiger Positionierungen verursachen. @Matt gab Ihnen einige gute Links zu diesem Thema Einige gute Ressourcen:</p> <p><a href="http://www.dayofjs.com/videos/22158462/web-browsers_alex-russel" rel="noreferrer">http://www.dayofjs.com/videos/22158462/web-browsers_alex-russel</a> Alex Russell geht etwa 36 Minuten lang ausführlich darauf ein, wie Webkit CSS analysiert, wie Reflows und Repaints funktionieren und was sie auslösen.</p> <p><a href="http://code.google.com/speed/page-speed/docs/rendering.html" rel="noreferrer">http://code.google.com/speed/page-speed/docs/rendering.html</a> Dies ist ein grundlegender Artikel darüber, wie man das Rendern von CSS optimiert</p></x-turndown>

0 Stimmen

Sehr interessantes Video, aber ich habe nicht gefunden, wonach ich gesucht habe, obwohl der von Ihnen hervorgehobene Abschnitt gut erklärt, wie die CSS-Selektorspezifität funktioniert. Um es klar auszudrücken, frage ich nicht, wie man Dinge schneller macht, sondern vielmehr nach einer Erklärung, wie/wann die CSS-Styles tatsächlich angewendet werden oder wie sie vom Stylesheet an den Browser oder Rendering-Engine übermittelt werden. Ihre Antwort: Lädt alle CSS herunter und beginnt dann mit der Darstellung des Dokuments von oben nach unten. klingt zwar korrekt, aber ich kann keine Referenzen oder Fakten finden, die dies unterstützen oder dementieren, abgesehen von meinen eigenen (wahrscheinlich fehlerhaften) Experimenten.

1 Stimmen

@Wesley Ich habe tatsächlich deine Frage beantwortet, wie und wann Stile angewendet werden. Stile werden gegen die DOM-Elemente von oben nach unten angewendet, da HTML als Stream betrachtet wird. Genauer gesagt überprüft der Browser für jedes Element das Stylesheet auf potenzielle CSS-Übereinstimmungen (es liest CSS von rechts nach links) und wendet dann die entsprechenden Stile an (WIE). Sie treten erst in Kraft, wenn alle CSS heruntergeladen sind, und dann beginnt der Browser mit dem Malen der Seite (WANN). In meinen beiden Links, sowie dem snook.ca-Link von Matt, werden die präsentierten Fakten dies tatsächlich unterstützen.

1 Stimmen

Der spezifische Teil, nach dem ich Referenz suche, lautet: Sie treten erst in Kraft, wenn alle CSS-Dateien heruntergeladen sind. Liegt das an der Rendering-Engine oder "so funktioniert es einfach"? In meinem Test (der Ihre Aussagen zu bestätigen scheint) war das einzige Tag mit CSS-Regeln und wurde nicht nach dem Herunterladen des CSS eingeführt, sondern vorher (es sei denn, Sie sagen, dass das Schließungszeichen erforderlich war, damit das Element erkannt wird). Der Test ist auch mit Inline-style am html-Tag fehlgeschlagen, was interessant und unerwartet war. Außerdem frage ich mich, ob das Herunterladen des CSS den HTML-Code blockiert oder nicht.

1voto

Pragatheeswaran Punkte 120

Ich bin mir nicht sicher über die markierte Antwort. Ich bezweifle ihre Richtigkeit. Laut diesem Link von Google Developers lädt der Browser zuerst die HTML-Datei herunter und wenn er eine CSS-Datei sieht, die zu einer externen Ressource verlinkt ist, beginnt er mit dem Herunterladen der CSS-Datei, während er gleichzeitig die DOM-Struktur für die gegebene HTML-Datei erstellt, da CSS die DOM nicht beeinflusst. Beachten Sie, dass keine Styles auf das Dokument angewendet werden, wenn der Browser die CSS-Datei herunterlädt.

Nach dem Herunterladen der CSS-Datei (angenommen, es gibt keine Skriptdateien) und wenn der DOM-Aufbau abgeschlossen ist, beginnt der Browser damit, die CSS-Eigenschaften auf diese Knoten im DOM-Baum abzubilden. Anschließend erstellt er einen weiteren Baum namens Renderbaum, der alle Objekte erstellt, die angezeigt werden sollen, als Rechtecke. Erst nach Abschluss des Renderbaums beginnt er mit dem Malen auf den Bildschirm.

Zusammengefasst:

  • Der Browser lädt die CSS-Datei vollständig herunter.
  • Der Browser wendet keine Styles auf die Seite an, während er herunterlädt. Er beginnt erst nach Abschluss des Downloads mit dem Zuordnen der Regeln.
  • Die Regeln werden nur während der Erstellung des Renderbaums angewendet.
  • Das Herunterladen der CSS-Datei blockiert nicht den HTML-Download. Sie müssen beachten, dass der Browser

Lädt zunächst alle HTML-Dateien herunter und dann werden Stil- und Skriptdateien heruntergeladen.

Sie können die Chrome-Entwicklerkonsole verwenden, um dies zu überprüfen. Verwenden Sie den Registerkarte "Timeline", um all dies zu sehen.

Ein Beispiel des Zeitachsenbilds ist hier zu sehen hier. Der Link, den ich am Anfang dieser Antwort gepostet habe, erklärt alles.

0 Stimmen

0 Stimmen

Ich denke, der OP hat nachgefragt, wie CSS-Stile angewendet werden und nicht nach der Reihenfolge des Renderings einer HTML-Seite.

0 Stimmen

Es wäre unmöglich für CSS, bereits angefordertes HTML download zu blockieren - die Frage ist, ob das Parsen/Rendern blockiert wird. Und beachten Sie: Das von Ihnen verlinkte Dokument sagt, dass die von Ihnen zusammengefasste Sequenz eine Vereinfachung ist - vieles passiert parallel: "Für ein besseres Benutzererlebnis wird der Rendering-Engine versuchen, Inhalte so schnell wie möglich auf dem Bildschirm anzuzeigen. Es wird nicht warten, bis das gesamte HTML analysiert ist, bevor mit dem Aufbau und der Layoutierung des Render-Baums begonnen wird. Teile des Inhalts werden analysiert und angezeigt, während der Prozess mit dem Rest des Inhalts, der weiterhin aus dem Netzwerk kommt, fortgesetzt wird."

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X