Website-Rendering 101

Sie geben den Namen der Site in die Adressleiste des Browsers ein, drücken die Eingabetaste und sehen aus Gewohnheit die angeforderte Seite. Es ist ganz einfach: Ich habe den Namen der Site eingegeben - die Site wurde angezeigt. Für die Neugierigen möchte ich Ihnen jedoch mitteilen, was passiert, wenn der Browser Teile der Site empfängt (ja, die Site wird in Teilen, mit anderen Worten, Blöcken, angezeigt) und eine vollständig gezeichnete Seite anzeigt.




Wie funktioniert der Browser?


Vor der Darstellung, wie der Browser die Seite erstellt, ist es wichtig zu verstehen, wie sie organisiert ist, welche Prozesse und auf welcher Ebene sie ausgeführt werden. Wenn wir mit dem Rendering-Prozess vertraut sind, werden wir die Komponenten des Browsers mehrmals aufrufen. Unter der Haube sieht der Browser also so aus:



Die Benutzeroberfläche ist alles, was der Benutzer sieht: Adressleiste, Vor- / Zurück-Schaltflächen, Menüs, Lesezeichen - mit Ausnahme des Bereichs, in dem die Site angezeigt wird.

Die Browser-Engine ist für die Interaktion zwischen der Benutzeroberfläche und der Rendering-Engine verantwortlich. Wenn Sie beispielsweise auf die Schaltfläche "Zurück" klicken, wird der RE-Komponente mitgeteilt, dass der vorherige Status gezeichnet werden muss.

Die Rendering Engine ist für die Anzeige der Webseite verantwortlich. Abhängig vom Dateityp kann diese Komponente sowohl HTML / XML und CSS als auch PDF analysieren und rendern.

Das Netzwerk führt xhr-Anforderungen für Ressourcen aus. Im Allgemeinen kommuniziert der Browser über diese Komponente mit dem Rest des Internets, einschließlich Proxys, Caches usw.

JS Engine ist der Ort, an dem JS-Code analysiert und ausgeführt wird.

Das UI-Backend dient zum Zeichnen von Standardkomponenten wie Kontrollkästchen, Eingaben und Schaltflächen.

Die Datenpersistenz ist für das Speichern lokaler Daten wie Cookies, SessionStorage, indexDB usw. verantwortlich.

Als Nächstes lernen wir, wie die betrachteten Browserkomponenten miteinander interagieren, und analysieren detaillierter, was in der Rendering-Engine geschieht. Mit anderen Worten …

Wie übersetzt der Browser HTML in Pixel auf dem Bildschirm?


Mit Hilfe der Netzwerkkomponente begann der Browser, die HTML-Datei mit Datenblöcken (normalerweise 8 KB) zu empfangen. Wie geht es weiter? Und dann folgt das Parsen (Prozessspezifikation) und Rendern dieser Datei in der Komponente, wie Sie vielleicht vermutet haben - die Rendering-Engine.

Wichtig! Um die Benutzerfreundlichkeit zu erhöhen, wartet der Browser nicht, bis alle HTML-Dateien geladen und analysiert wurden. Stattdessen versucht der Browser sofort, die Seite dem Benutzer anzuzeigen (im Folgenden wird überlegt, wie).

Der Parsing-Prozess selbst sieht folgendermaßen aus:



Das Ergebnis des Parsens ist ein DOM-Baum . Nehmen Sie zum Beispiel den folgenden HTML-Code:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Web Rendering</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="wrapper"> <div class="header"> <h1>Hey</h1> </div> <div class="content"> <p> Lorem <span>ipsum</span>. </p> </div> <footer> Contact me </footer> </div> <script src="./code.js"></script> </body> </html> 


Der DOM-Baum einer solchen HTML-Datei sieht folgendermaßen aus:



Wenn der Browser die HTML-Datei analysiert, stößt er auf Tags, die Links zu Ressourcen von Drittanbietern enthalten ( <link>, <script>, <img> und so weiter) - sobald sie entdeckt werden, erfolgt eine Anforderung für diese Ressourcen.

Senden Sie also eine Anfrage an die Adresse, die im href-Attribut des Tags angegeben ist <link rel = "stylessheet"> Nachdem der Browser die CSS- Styles-Datei erhalten hat, analysiert er diese Datei und erstellt das sogenannte CSS-Objektmodell (CSSOM) .

Stellen Sie sich vor, wir haben ein solches Stylesheet:

 body { font-size: 14px; } .wrapper { width: 960px; margin: 0 auto; } .wrapper .header h1 { font-size: 26px; } .wrapper p { color: red; } footer { padding: 20px 0; } 


Daraus erhalten wir diese CSSOM :



Achtung: Hier wird ein Baum aus den Stilen unserer CSS-Datei erstellt. Darüber hinaus gibt es Stile des Benutzeragenten - Standardbrowser- und Inline-Stile -, die in HTML-Tags festgelegt sind.

Weitere Informationen zum Parsing-Algorithmus für CSS-Stile finden Sie in der Spezifikation .

Jetzt haben wir das DOM und CSSOM - das erste beantwortet die Frage "Was?", Das zweite beantwortet die Frage "Wie?". Wenn Sie der Meinung sind, dass der nächste Schritt darin besteht, DOM und CSSOM zu kombinieren, dann haben Sie absolut Recht! DOM + CSSOM = Baum rendern.

Renderbaum ist ein Baum sichtbarer (!) Elemente, der in der Reihenfolge erstellt wird, in der sie auf der Seite gerendert werden sollen. Beachten Sie, dass Elemente mit der CSS-Regel nicht im Render-Baum angezeigt werden: Keine oder andere Elemente, die sich negativ auf die Anzeige auswirken.

Der Browser erstellt den Render-Baum, um genau zu bestimmen, was und in welcher Reihenfolge gerendert werden soll. Die Konstruktion des Render-Baums sieht ungefähr so ​​aus: Ausgehend vom Root-Element (HTML) durchläuft der Parser alle sichtbaren Elemente (Sprunglink, Skript, Meta, durch CSS-Elemente verborgen) und findet für jedes sichtbare Element die entsprechende CSS-Regel aus CSSOM.

In der Firefox-Engine werden Render Tree-Elemente als Frames bezeichnet. Webkit verwendet den Begriff Renderer oder Renderobjekt. Render-Objekt weiß, wie es sich auf der Seite platziert, und enthält auch Informationen zu seinen untergeordneten Objekten. Und für die Neugierigsten, wenn Sie sich den Quellcode des Webkits ansehen, finden Sie eine Klasse namens RenderObject .

Wenn wir unser Beispiel fortsetzen, erhalten wir einen solchen Render-Baum :



Momentan haben wir in einigen Staaten einen Render-Baum - einen Baum, der Informationen darüber enthält, was und wie gezeichnet werden soll. Jetzt muss der Browser verstehen, wo und mit welcher Größe das Element angezeigt wird. Die Berechnung von Position und Größe wird als Layout bezeichnet .

Layout ist ein rekursiver Prozess zum Bestimmen der Position und Größe von Elementen aus einem Render-Baum. Sie beginnt beim ursprünglichen Render-Objekt und durchläuft einen Teil oder die gesamte Baumhierarchie rekursiv, wobei die geometrischen Abmessungen der untergeordneten Render-Objekte berechnet werden. Das Stammelement hat eine Position (0,0) und seine Größe entspricht der Größe des sichtbaren Teils des Fensters, dh der Größe des Ansichtsfensters.

HTML verwendet ein flussbasiertes Layoutmodell. Mit anderen Worten, die geometrischen Abmessungen von Elementen können in einigen Fällen in einem Durchgang berechnet werden (wenn die Elemente, die später im Stream angezeigt werden, sich nicht auf die Position und Größe der bereits übergebenen Elemente auswirken).

Das Layout kann global sein, wenn die Position der Renderobjekte des gesamten Baums berechnet werden muss, und inkrementell, wenn nur ein Teil des Baums berechnet werden muss. Das globale Layout tritt beispielsweise beim Ändern der Schriftgröße oder während des Größenänderungsereignisses auf. Inkrementelles Layout wird nur für Renderobjekte verwendet, die als verschmutzt markiert sind.

Ein paar Worte zum "Dirty-Bit-System" . Dieses System wird von Browsern verwendet, um den Prozess so zu optimieren, dass nicht das gesamte Layout nachgezählt wird. Wenn Sie ein neues hinzufügen oder ein vorhandenes Render-Objekt ändern, werden er und seine Kinder mit der Markierung "Dirty" gekennzeichnet. Wenn sich das Render-Objekt nicht ändert, seine untergeordneten Objekte jedoch geändert oder hinzugefügt wurden, wird dieses Render-Objekt als "untergeordnete Objekte sind verschmutzt" markiert.

Gegen Ende des Layoutvorgangs hat jedes Renderobjekt seine eigene Position und Größe.

Zusammenfassend: Der Browser weiß, was, wie und wo zu zeichnen ist. Deshalb - es bleibt nur zu zeichnen. Seltsamerweise nennt man diesen Vorgang Paint .

Malen - die Phase, in der das Monitorpixel mit der in den Eigenschaften des Renderobjekts angegebenen Farbe gefüllt wird und der weiße Bildschirm sich in ein vom Autor (Entwickler) konzipiertes Bild verwandelt. Während des gesamten Rendering-Pfads ist dies der teuerste Prozess (nicht, dass der vorherige kostengünstig ist).

Neben dem Layout-Prozess kann Paint global sein - der Baum wird vollständig und inkrementell neu gezeichnet - der Baum wird teilweise neu gezeichnet. Beim teilweisen Neuzeichnen markiert ein Render-Objekt sein Rechteck als ungültig. Das Betriebssystem betrachtet diesen Bereich als neu zu zeichnend und löst das Paint-Ereignis aus. Gleichzeitig ist der Browser in der Lage, Bereiche zu kombinieren, um an allen Stellen, an denen dies erforderlich ist, eine sofortige Neuzeichnung durchzuführen.

Die Dimensionierung und Positionierung von Baumelementen (Layout) und das Neuzeichnen (Malen) sind kostspielige Prozesse. Sie laufen auf CPU-Ebene. Durch die Entwicklung dynamischer Webanwendungen, in denen diese Prozesse sehr oft gestartet werden, werden wir niemals reibungslose Animationen erzielen.

Es muss also eine Möglichkeit geben, Websites mit umfangreichen Animationen zu erstellen, ohne die CPU zu belasten und die einzelnen Frames in weniger als 16,6 ms (60 fps) zu zeichnen. In der Tat führt der Browser einen weiteren Schritt durch, der zur Optimierung der Dynamik von Websites beiträgt - Composite (Komposition).

Vor der Komposition befinden sich alle gezeichneten Elemente auf einer Ebene (Memory-Ebene). Das heißt, das Ändern der Parameter (beispielsweise der geometrischen Abmessungen oder der Position) einiger Elemente erfordert die Neuberechnung der Parameter benachbarter Elemente. Wenn Sie jedoch Elemente auf zusammengesetzten Ebenen verteilen, bewirkt das Ändern der Parameter eines Elements eine Neuberechnung nur für eine bestimmte Ebene, ohne dass sich dies auf Elemente in anderen Ebenen auswirkt. Aus diesem Grund ist dieser Prozess in Bezug auf die Leistung am kostengünstigsten. Sie sollten daher versuchen, Änderungen vorzunehmen, die nur zu Composite führen.

Zusammenfassend erhalten wir den folgenden Prozess zum Rendern einer Webseite:



TLDR
Der Browser empfängt die HTML-Datei, analysiert sie und erstellt das DOM. Treffen Sie CSS-Stile, der Browser lädt sie, analysiert sie, erstellt CSSOM und kombiniert sie mit dem DOM. Wir erhalten den Render-Baum. Es bleibt abzuwarten, wo die Elemente im Renderbaum angeordnet werden sollen - dies ist die Aufgabe des Layouts. Nachdem Sie die Elemente angeordnet haben, können Sie mit dem Zeichnen beginnen - dies ist die Malaufgabe, die Phase, in der die Pixel des Bildschirms ausgefüllt werden.

Dynamik


Was passiert, wenn sich die CSS-Eigenschaft ändert? Oder wird zum Beispiel ein neuer Dom-Knoten hinzugefügt? Im Falle einer Änderung der CSS-Eigenschaften hängt alles von der geänderten Eigenschaft ab. Es gibt nur zwei Eigenschaften, die die zusammengesetzte Aufgabe auslösen - Deckkraft und Transformation . Nur diese beiden Eigenschaften sind für die Animation am günstigsten. Wenn Sie beispielsweise den Hintergrund ändern, wird die Malaufgabe (dann Composite) ausgeführt, und wenn Sie die Anzeige ändern, wird zuerst das Layout, dann das Malen und dann das Composite ausgeführt. Eine Liste der Aufgaben, die durch Stiländerungen verursacht werden, finden Sie unter csstriggers.com .

Beim Hinzufügen eines neuen Knotens zum Dom-Baum - offensichtlich muss der Browser dem Baum ein neues Objekt hinzufügen, seine Position auf der Seite berechnen, die Positionen anderer Elemente auf der Seite berechnen (wenn sie von einem neuen Element betroffen waren) und am Ende klingt alles teuer, um es zu zeichnen. Daher müssen Sie bei solchen Vorgängen die Leistung berücksichtigen, da nicht jeder Internetbenutzer Ihre Webanwendung auf dem neuesten Gerätemodell startet.

Zusammenfassend haben wir untersucht, aus welchen Komponenten der Browser besteht, wie sie miteinander interagieren und wie die Rendering-Engine die Seite für den Benutzer zeichnet.

Sie können das Obige in den Chrom-Devtools sehen, aber um nicht über den Titel des Artikels hinauszugehen, ist das alles fürs Erste.

Source: https://habr.com/ru/post/de484900/


All Articles