Omówienie architektury RenderingNG

Chris Harrelson
Chris Harrelson

W poprzednim poście omówiliśmy cele i najważniejsze właściwości architektury RenderingNG. W tym poście wyjaśnimy, jak są skonfigurowane jego elementy oraz jak przepływa przez nie potok renderowania.

Zaczynając od najwyższego poziomu, dochodzimy do następujących zadań renderowania:

  1. Renderuj zawartość na piksele na ekranie.
  2. Tworzyć efekty wizualne na przechodzeniu między stanami.
  3. Przewiń w odpowiedzi na dane wejściowe.
  4. Kieruj dane wejściowe efektywnie we właściwe miejsca, żeby skrypty dla programistów i inne podsystemy mogły na nie reagować.

Zawartość do wyrenderowania to drzewo ramek na każdej karcie przeglądarki wraz z interfejsem przeglądarki. A także strumień nieprzetworzonych zdarzeń wejściowych z ekranów dotykowych, myszy, klawiatur i innych urządzeń.

Każda ramka zawiera:

  • Stan DOM
  • CSS
  • Obszary robocze
  • Zasoby zewnętrzne, takie jak obrazy, filmy, czcionki czy SVG

Ramka to dokument HTML wraz z jego adresem URL. Strona wczytana na karcie przeglądarki zawiera ramkę najwyższego poziomu, ramki podrzędne dla każdego elementu iframe występującego w dokumencie najwyższego poziomu oraz ich rekurencyjne elementy podrzędne iframe.

Efekt wizualny to operacja graficzna zastosowana do bitmapy, np. przewijanie, przekształcanie, klip, filtr, nieprzezroczystość czy mieszanie.

Komponenty architektury

W RenderingNG te zadania są logicznie podzielone na kilka etapów i komponentów kodu. Komponenty trafiają do różnych procesów procesora, wątków i podkomponentów w tych wątkach. Każdy z nich odgrywa ważną rolę w osiąganiu niezawodności, skalowalności i elastyczności wszystkich treści internetowych.

Struktura potoku renderowania

Schemat procesu renderowania przedstawiony poniżej.

Renderowanie przebiega w ramach potoku z licznymi etapami i artefaktami utworzonymi. Każdy etap to kod, który wykonuje jedno dobrze zdefiniowane zadanie podczas renderowania. Artefakty to struktury danych, które są danymi wejściowymi lub wyjściowymi etapów. Na diagramach dane wejściowe i wyjści są oznaczone strzałkami.

W tym poście nie będziemy szczegółowo omawiać artefaktów. Omówimy je w następnym poście: Kluczowe struktury danych i ich role w RenderowaniuNG.

Etapy potoku

Na diagramie poprzedzającym etapy są oznaczone kolorami wskazującymi, w którym wątku lub procesie są wykonywane:

  • Zielony: wątek główny procesu renderowania
  • Żółty: kompozytor procesu renderowania
  • Pomarańczowy: widok procesu

W niektórych przypadkach mogą być wykonywane w wielu miejscach, w zależności od sytuacji, dlatego niektóre mają 2 kolory.

Etapy te są następujące:

  1. Animuj: zmieniaj style obliczeniowe i mutuj drzewa właściwości w czasie zgodnie z deklaratywnymi osiami czasu.
  2. Styl: zastosuj styl CSS do elementu DOM i utwórz style obliczeniowe.
  3. Układ: określ rozmiar i położenie elementów DOM na ekranie oraz utwórz stałe drzewo fragmentów.
  4. Wstępne renderowanie: oblicz drzewa właściwości i w razie potrzeby invalidate istniejące listy wyświetlania i kafelki tekstur GPU.
  5. Przewijanie: aktualizuj przesunięcie przewijania dokumentów i przewijanych elementów DOM, zmieniając drzewa właściwości.
  6. Paint: oblicza listę wyświetlania opisującą sposób rastrowania kafelków tekstur GPU z interfejsu DOM.
  7. Zatwierdzanie: kopiowanie drzewa właściwości i listy wyświetlania do wątku kompozytora.
  8. Warstwy:umożliwia podział listy wyświetlania na listę skomponowanych warstw na potrzeby niezależnej rasteryzacji i animacji.
  9. Rastrowanie, dekodowanie i malowanie Workletów: umożliwia przekształcanie list wyświetlanych, zakodowanego obrazów i malowania kodu Workletu w kafelki tekstur GPU.
  10. Aktywuj:utwórz ramkę kompozytora, która będzie przedstawiać, jak rysować i rozmieszczać kafelki GPU na ekranie, wraz z efektami wizualnymi.
  11. Agreguj: połącz klatki kompozytora ze wszystkich widocznych ramek kompozytora w jedną globalną ramkę kompozytora.
  12. Rysowanie: uruchom zagregowaną ramkę kompozytora w GPU, aby utworzyć piksele na ekranie.

Możesz pominąć etapy potoku renderowania, jeśli nie są potrzebne. Na przykład animacje efektów wizualnych i przewijanie mogą pomijać układ, wstępnie wyrenderowane i wyrenderowane. Dlatego animacje i przewijanie są oznaczone na diagramie żółtymi i zielonymi kropkami. Jeśli na potrzeby efektów wizualnych można pominąć układ, wstępne renderowanie i malowanie, można je w całości uruchomić w wątku kompozytora z pominięciem wątku głównego.

Renderowanie interfejsu przeglądarki nie zostało tu pokazane bezpośrednio, ale można je traktować jako uproszczoną wersję tego samego potoku (i w rzeczywistości korzysta z większej części kodu). Film (którego nie widać bezpośrednio) jest zwykle renderowany za pomocą niezależnego kodu, który dekoduje klatki w postaci kafelków tekstur GPU, które są następnie podłączane do ramek kompozytora i kroku rysowania.

Proces i struktura wątków

Procesy procesora

Zastosowanie kilku procesów CPU pozwala na uzyskanie wydajności i bezpieczeństwa między witrynami i stanem przeglądarki, a także zapewnia stabilność i bezpieczeństwo od sprzętu GPU.

Schemat różnych części procesów procesora

  • Proces renderowania renderuje, animuje, przewija i przekierowuje dane wejściowe pojedynczej kombinacji witryny i karty. Istnieje wiele procesów renderowania.
  • Proces przeglądarki renderuje, animuje i przekierowuje dane wejściowe interfejsu przeglądarki (w tym pasek adresu URL, tytuły kart i ikony), a także kieruje wszystkie pozostałe dane do odpowiedniego procesu renderowania. Istnieje dokładnie jeden proces przeglądarki.
  • Proces Viz agreguje komponowanie z różnych procesów renderowania oraz z procesu przeglądarki. Rasuje i rysuje za pomocą GPU. Istnieje dokładnie 1 proces Viz.

Różne witryny zawsze trafiają w różny sposób do różnych procesów renderowania. W rzeczywistości zawsze na komputerze, a w miarę możliwości na urządzeniu mobilnym. Piszę „zawsze” poniżej, ale to zastrzeżenie obowiązuje przez cały czas).

Wiele kart lub okien przeglądarki z tej samej witryny korzysta zwykle z różnych procesów renderowania, chyba że karty są ze sobą powiązane (jedna strona otwiera drugą). W przypadku dużego obciążenia pamięci na komputerze Chromium może umieścić wiele kart z tej samej strony w tym samym procesie renderowania, nawet jeśli nie są one ze sobą powiązane.

Na jednej karcie przeglądarki ramki z różnych witryn zawsze podlegają różnym procesom renderowania, ale te z tej samej witryny zawsze korzystają z tego samego procesu renderowania. Z perspektywy renderowania ważną zaletą wielu procesów renderowania jest to, że elementy iframe i karty występujące w różnych witrynach zapewniają izolację wydajności od siebie. Dodatkowo źródła mogą uzyskać jeszcze większą izolację.

W całym Chromium jest dokładnie jeden proces Viz. W końcu wyświetla się zwykle tylko 1 GPU i 1 ekran. Oddzielenie Viz od własnych procesów zapewnia stabilność w obliczu błędów związanych ze sterownikami lub sprzętem GPU. Jest to też przydatne w przypadku izolacji zabezpieczeń, co jest ważne w przypadku interfejsów API GPU, takich jak Vulkan. Jest też ważna dla ogólnie bezpieczeństwa.

Przeglądarka może mieć wiele kart i okien, a wszystkie mają do rysowania piksele interfejsu przeglądarki, możesz więc zastanawiać się, dlaczego w przeglądarce jest dokładnie jeden proces? Powodem jest to, że w danym momencie aktywna jest tylko jedna z nich. Niewidoczne karty przeglądarki są w większości dezaktywowane i zbierają całą pamięć GPU. Jednak złożone funkcje renderowania interfejsu przeglądarki są coraz częściej wdrażane w procesach renderowania (nazywanych WebUI). Dzieje się tak nie ze względu na izolację wydajności, ale po to, aby wykorzystać łatwość korzystania z silnika renderowania stron internetowych w Chromium.

Na starszych urządzeniach z Androidem renderowanie i proces przeglądarki są wspólne, jeśli są używane w komponencie WebView (nie dotyczy to ogólnie Chromium na Androidzie, tylko WebView). W komponencie WebView proces przeglądarki jest też udostępniany aplikacji do umieszczania danych, a komponent WebView ma tylko 1 proces renderowania.

Czasami dostępne są też narzędzia do dekodowania chronionych treści wideo. Ten proces nie został opisany powyżej.

Wątki

Wątki pomagają uzyskać izolację wydajności i czas reagowania pomimo powolnych zadań, równoległego przetwarzania potoków i wielu buforowania.

Diagram procesu renderowania zgodnie z opisem w artykule.

  • W wątku głównym uruchamia się skrypty, pętla zdarzeń renderowania, cykl życia dokumentu, testowanie działań, wysyłanie zdarzeń skryptu i analizowanie formatów danych HTML, CSS i innych.
    • Pomocnicy wątków głównych wykonują takie zadania jak tworzenie bitmap obrazów i obiektów blob, które wymagają kodowania lub dekodowania.
    • Skrypty Web Workers uruchamiają skrypt i pętlę zdarzeń renderowania dla OffscreenCanvas.
  • Wątek kompozytora przetwarza zdarzenia wejściowe, wykonuje przewijanie i animacje treści internetowych, oblicza optymalną warstwowość treści internetowych oraz koordynuje dekodowanie obrazów, Worklety malowania i zadania rastrowe.
    • Narzędzia pomocnicze wątków kompozytorów koordynują zadania rastrowania Viz oraz wykonują zadania dekodowania obrazów, maluj worklety i rastry zapasowe.
  • Wątki multimediów, demuksera i wyjścia audio dekodują, przetwarzają i synchronizują strumienie wideo i audio. Pamiętaj, że film jest uruchamiany równolegle z głównym potokiem renderowania.

Oddzielenie wątków głównych i kompozytorów jest niezwykle ważne dla izolacji wydajności animacji i przewijania od pracy wątku głównego.

Na każdy proces renderowania przypada tylko jeden wątek główny, chociaż wiele kart lub ramek z tej samej witryny może znaleźć się w tym samym procesie. Zapewnia to jednak odizolowanie wydajności do pracy wykonywanej przy użyciu różnych interfejsów API przeglądarek. Na przykład generowanie obrazu bitmapowego i obiektów blob w interfejsie Canvas API jest uruchamiane w wątku pomocniczym głównego wątku.

Podobnie jest tylko jeden wątek kompozytora na proces renderowania. Zasadniczo nie ma problemu, że istnieje tylko jeden, ponieważ wszystkie bardzo drogie operacje w wątku kompozytora są przekazywane albo do wątków instancji roboczych kompozytora, albo do procesu Viz, a pracę można wykonywać równolegle z routingiem danych wejściowych, przewijaniem lub animacją. Wątki instancji roboczych kompozytora koordynują zadania wykonywane w procesie Viz, ale akceleracja GPU w każdym miejscu może zakończyć się niepowodzeniem z przyczyn niezależnych od Chromium, takich jak błędy sterownika. W takich sytuacjach wątek instancji roboczej wykona pracę w trybie zastępczym procesora.

Liczba wątków instancji roboczych kompozytora zależy od możliwości urządzenia. Na przykład komputery zwykle wykorzystują więcej wątków, ponieważ mają więcej rdzeni procesora i mają mniej energii baterii niż urządzenia mobilne. Oto przykład skalowania w górę i w dół.

Warto też zauważyć, że architektura wątków procesu renderowania wykorzystuje 3 różne wzorce optymalizacji:

  • Wątki pomocnicze: wysyłanie długo trwających podzadań do dodatkowych wątków, aby wątek nadrzędny odpowiadał na inne żądania wykonywane w tym samym czasie. Dobrymi przykładami tej techniki są wątki pomocnicze głównego wątku i wątki pomocnicze kompozytora.
  • Buforowanie wielu treści: pokazywanie wcześniej wyrenderowanych treści podczas renderowania nowych treści, co pozwala ukryć opóźnienie renderowania. Wątek kompozytora korzysta z tej metody.
  • Równoległe wczytywanie potoku: potok renderowania uruchamia się jednocześnie w wielu miejscach. W ten sposób przewijanie i animacje mogą być szybkie nawet w przypadku aktualizacji renderowania wątku głównego, ponieważ przewijanie i animacja mogą być wykonywane równolegle.

Proces przeglądarki

Diagram procesu przeglądarki przedstawiający relację między wątkiem renderowania i komponowania oraz aplikacją pomocniczą wątku renderowania i komponowania.

  • Wątek renderowania i komponowania odpowiada na dane wejściowe w interfejsie przeglądarki, przekazuje inne dane wejściowe do prawidłowego procesu renderowania oraz określa i maluje interfejs przeglądarki.
  • Pomoce wątków renderowania i komponowania wykonują zadania dekodowania obrazów oraz zastępcze rastry lub dekodowanie.

Przetwarzanie i komponowanie wątku w procesie przeglądarki jest podobne do kodu i funkcjonalności procesu renderowania. Różnica polega na tym, że wątek główny i wątek kompozytora są łączone w jeden wątek. W tym przypadku potrzebny jest tylko 1 wątek, ponieważ nie ma potrzeby izolacji wydajności od długich zadań w wątku głównym, ponieważ nie ma on z założenia żadnego wątku.

Proces wyświetlania

Diagram pokazujący, że proces Viz zawiera wątek główny GPU i wątek kompozytora wyświetlacza.

  • Wątek główny GPU wyświetla listy i klatki wideo jako kafelki tekstur GPU oraz rysuje klatki kompozytora na ekran.
  • Wątek komponentu displayowego gromadzi i optymalizuje komponowanie z każdego procesu renderowania i procesu przeglądarki w jedną ramkę kompozytora do prezentacji na ekranie.

Rastrowanie i rysowanie zazwyczaj odbywają się w tym samym wątku, ponieważ obie opierają się na zasobach GPU, co sprawia, że trudno jest niezawodne korzystać z GPU w wielu wątkach (łatwiejszy dostęp wielowątkowy do GPU to jedna z motywacji do opracowania nowego standardu Vulkan). W komponencie WebView Androida istnieje osobny wątek renderowania na poziomie systemu operacyjnego, ponieważ komponenty WebView są osadzone w aplikacji natywnej. W przyszłości na innych platformach prawdopodobnie będzie taki wątek.

Kompozytor wyświetlania znajduje się w innym wątku, ponieważ musi odpowiadać przez cały czas i nie blokować żadnych możliwych źródeł spowalniania działania głównego wątku GPU. Jedną z przyczyn spowalniania pracy głównego wątku GPU jest wywoływanie kodu innego niż Chromium, na przykład specyficznych dla dostawcy sterowników GPU, które mogą działać wolno w trudny do przewidzenia sposób.

Struktura komponentów

W każdym głównym wątku procesu renderowania lub wątku kompozytora występują logiczne komponenty oprogramowania, które wchodzą ze sobą w uporządkowany sposób.

Renderowanie głównych komponentów wątku procesu renderowania

Schemat mechanizmu renderowania Blink.

  • Mechanizm renderowania migania:
    • Fragment drzewa ramki lokalnej reprezentuje drzewo ramek lokalnych i element DOM w ramkach.
    • Komponent Interfejsy API DOM i Canvas zawiera implementacje wszystkich tych interfejsów API.
    • Uruchamiający cykl życia dokumentu wykonuje kroki potoku renderowania, które obejmują krok zatwierdzenia.
    • Komponent testowanie i wysyłanie zdarzeń wejściowych przeprowadza testy trafień, aby sprawdzić, na który element DOM jest kierowane zdarzenie, oraz uruchamia algorytmy wysyłające zdarzenie wejściowe oraz domyślne zachowania.
  • Harmonogram i runner pętli zdarzeń renderowania decyduje o tym, co i kiedy uruchamiać w pętli zdarzeń. Planuje renderowanie z częstotliwością odpowiadającą wyświetlaczowi urządzenia.

Schemat drzewa ramek.

Lokalne fragmenty drzewa ramek są dość skomplikowane. Pamiętaj, że drzewo ramek to strona główna i jej podrzędne elementy iframe – rekurencyjnie. Ramka jest lokalna w procesie renderowania, jeśli jest renderowana w tym procesie. W przeciwnym razie jest zdalna.

Możesz sobie wyobrazić kolorowanie ramek według procesu renderowania. Na poprzednim obrazie zielone okręgi to wszystkie klatki w jednym procesie renderowania; pomarańczowe – w drugim, a niebieskie – w trzecim.

Lokalna ramka drzewa ramek to połączony komponent tego samego koloru w drzewie ramek. Na ilustracji widać 4 lokalne drzewa ramek: 2 dla lokalizacji A, 1 dla witryny B i 1 dla witryny C. Każde lokalne drzewo ramek otrzymuje własny komponent mechanizmu renderowania Blink. Mechanizm renderowania Blink w lokalnym drzewie ramek może, ale nie musi, uczestniczyć w tym samym procesie renderowania co inne lokalne drzewa ramek (jest to ustalane na podstawie sposobu wyboru procesu renderowania, jak opisano wcześniej).

Struktura wątku kompozytora procesu renderowania

Diagram przedstawiający komponenty kompozytora procesu renderowania.

Komponenty kompozytora procesu renderowania to:

  • Moduł obsługi danych, który utrzymuje listę skomponowanych warstw, listy wyświetlania i drzewa właściwości.
  • Program uruchamiający cykl życia, który uruchamia animacje, przewijanie, kompozycje, rastrowanie i dekodowanie oraz aktywuje kroki potoku renderowania. Pamiętaj, że tworzenie animacji i przewijanie może odbywać się zarówno w wątku głównym, jak i w kompozytorze.
  • Moduł obsługi danych wejściowych i testowych wykonuje przetwarzanie danych wejściowych i testowanie trafień w rozdzielczości skomponowanych warstw, aby określić, czy w wątku kompozytora można uruchamiać gesty przewijania i które testy trafień w procesie renderowania mają być celem.

Przykład w praktyce

Na przykładzie skoncentrujmy się na architekturze. W tym przykładzie widoczne są 3 karty:

Karta 1: foo.com

<html>
  <iframe id=one src="foo.com/other-url"></iframe>
  <iframe  id=two src="bar.com"></iframe>
</html>

Karta 2: bar.com

<html>
 …
</html>

Karta 3: baz.com html <html> … </html>

Proces, wątek i struktura komponentów tych kart będą wyglądać tak:

Schemat procesu obsługi kart.

Przyjrzyjmy się teraz każdemu z 4 głównych zadań renderowania. Jak zapewne pamiętasz, to:

  1. Renderuj zawartość na piksele na ekranie.
  2. Tworzyć efekty wizualne, przechodząc z jednego stanu do drugiego.
  3. Przewiń w odpowiedzi na dane wejściowe.
  4. Kieruj dane wejściowe w odpowiednie miejsca, tak by skrypty programistów i inne podsystemy mogły na nie reagować.

Aby wyrenderować zmieniony DOM na pierwszej karcie:

  1. Skrypt programisty zmienia DOM w procesie renderowania domeny foo.com.
  2. Mechanizm renderowania Blink informuje kompozytor, że wymaga renderowania.
  3. Kompozytor informuje systemu Viz, że musi przeprowadzić renderowanie.
  4. Viz sygnalizuje kompozytorowi rozpoczęcie renderowania.
  5. Kompozytor przekazuje sygnał startowy do mechanizmu renderowania Blink.
  6. Uruchomienie pętli zdarzeń głównego wątku uruchamia cykl życia dokumentu.
  7. Wątek główny wysyła wynik do wątku kompozytora.
  8. Uruchamiający pętlę zdarzeń kompozytora uruchamia cykl życia komponowania.
  9. Wszystkie zadania rastrowe są wysyłane do Viz na potrzeby rastrowania (często jest więcej niż jedno z tych zadań).
  10. Wyświetlanie treści przez GPU.
  11. Viz potwierdza wykonanie zadania rastrowego. Uwaga: Chromium często nie czeka na zakończenie działania rastrowego. Zamiast tego używa tak zwanego tokena synchronizacji, który musi zostać rozwiązany przez zadania rastrowe przed wykonaniem kroku 15.
  12. Ramka kompozytora jest wysyłana do Viz.
  13. Viz agreguje ramki kompozytora dla procesu renderowania foo.com, procesu renderowania elementów iframe bar.com i interfejsu przeglądarki.
  14. Viz zaplanuje remis.
  15. Viz rysuje zagregowaną ramkę kompozytora na ekran.

Aby animować przejście przekształcenia CSS na drugiej karcie:

  1. Wątek kompozytora dla procesu renderowania bar.com zaznacza animację w swojej pętli zdarzeń kompozytora, modyfikując istniejące drzewa właściwości. To spowoduje ponowne uruchomienie cyklu życia kompozytora. (mogą występować zadania rastrowania i dekodowania, ale nie są one tutaj pokazane).
  2. Ramka kompozytora jest wysyłana do Viz.
  3. Viz agreguje ramki kompozytora dla procesu renderowania foo.com, procesu renderowania bar.com i interfejsu przeglądarki.
  4. Viz zaplanuje remis.
  5. Viz rysuje zagregowaną ramkę kompozytora na ekran.

Aby przewinąć stronę internetową na karcie trzeciej:

  1. Proces przeglądarki zatrzymuje się w sekwencji zdarzeń input (myszki, dotyku lub klawiatury).
  2. Każde zdarzenie jest kierowane do wątku kompozytora procesu renderowania baz.com.
  3. Kompozytor określa, czy wątek główny musi mieć dostęp do informacji o zdarzeniu.
  4. W razie potrzeby zdarzenie jest wysyłane do wątku głównego.
  5. Wątek główny uruchamia detektory zdarzeń input (pointerdown, touchstar, pointermove, touchmove lub wheel), aby sprawdzić, czy detektory wywołają zdarzenie preventDefault.
  6. Wątek główny zwraca informację o tym, czy do kompozytora została wywołana funkcja preventDefault.
  7. Jeśli nie, zdarzenie wejściowe jest wysyłane z powrotem do procesu przeglądarki.
  8. Proces przeglądarki konwertuje go na gest przewijania, łącząc go z innymi ostatnimi zdarzeniami.
  9. Gest przewijania jest wysyłany ponownie do wątku kompozytora procesu renderowania baz.com.
  10. Tam odbywa się przewijanie, a wątek kompozytora w przypadku procesu renderowania bar.com zaznacza animację w pętli zdarzeń kompozytora. Spowoduje to zmianę przesunięcia przewijania w drzewach właściwości i ponowne uruchomienie cyklu życia kompozytora. Informuje też wątek główny o uruchomieniu zdarzenia scroll (którego nie ma w tym miejscu).
  11. Ramka kompozytora jest wysyłana do Viz.
  12. Viz agreguje ramki kompozytora dla procesu renderowania foo.com, procesu renderowania bar.com i interfejsu przeglądarki.
  13. Viz zaplanuje remis.
  14. Viz rysuje zagregowaną ramkę kompozytora na ekran.

Aby przekierować zdarzenie click w hiperlinku w elemencie iframe #2 na pierwszej karcie:

  1. Zdarzenie usługi input (myszka, dotyk lub klawiatura) wpływa na proces przeglądarki. Przeprowadza w przybliżeniu test działania, by ustalić, że proces renderowania elementu iframe bar.com powinien odbierać kliknięcie i wysyłać je do niego.
  2. Wątek kompozytora dla bar.com kieruje zdarzenie click do wątku głównego witryny bar.com i planuje zadanie pętli zdarzeń renderowania, które ma je przetworzyć.
  3. Procesor zdarzeń wejściowych do testowania trafień głównego wątku witryny bar.com w celu określenia, który element DOM w elemencie iframe został kliknięty, i uruchamia zdarzenie click, które ma być obserwowane przez skrypty. Element „preventDefault” nie słyszy, więc przejdzie do hiperlinku.
  4. Po wczytaniu strony docelowej hiperlinku renderowany jest nowy stan, zgodnie z krokami podobnymi do powyższego przykładu „renderowania zmienionego DOM”. (Te kolejne zmiany nie są tu pokazane).

Podsumowanie

To było dużo szczegółów. Jak widać, renderowanie w Chromium jest dość skomplikowane. Zapamiętanie i zapamiętanie wszystkich elementów może zająć dużo czasu, więc nie martw się, jeśli wydają się przytłaczające.

Najważniejszą kwestią jest to, że istnieje koncepcyjnie prosty potok renderowania, który przez starannej modularyzacji i dbałości o szczegóły został podzielony na wiele niezależnych komponentów. Komponenty te zostały podzielone między równoległe procesy i wątki, aby zmaksymalizować skalowalność i możliwości związane z elastycznością.

Każdy z nich odgrywa kluczową rolę w zapewnianiu wydajności i funkcjonalności, jakich potrzebują nowoczesne aplikacje internetowe. Wkrótce opublikujemy szczegółowe omówienie każdego z nich i ważnych ról, jakie pełnią.

Jednak najpierw wyjaśnię, dlaczego kluczowe struktury danych wymienione w tym poście (oznaczone na niebiesko po bokach diagramu potoku renderowania) są tak samo ważne dla RenderingNG jak komponenty kodu.

Dziękuję za przeczytanie i prosimy o cierpliwość.

Ilustracje: Una Kravets.