RenderingNG

Dostosowanie do nowej generacji treści internetowych

Chris Harrelson
Chris Harrelson

Nazywam się Chris Harrelson i jestem kierownikiem zespołu inżynierów ds. renderowania (czyli przekształcania kodu HTML i CSS w piksele) w Blink. Od ponad 8 lat testuję wydajność renderowania w internecie. Dążę do tego, aby robić wszystko, co w mojej mocy, aby korzystanie z internetu było szybsze, łatwiejsze i bardziej niezawodne. Z przyjemnością opowiem Ci o tym, co zrobiliśmy w tym czasie, aby stworzyć nową, najnowocześniejszą architekturę silnika renderowania Chromium. Osiągnęliśmy to dzięki wsparciu. Mam nadzieję, że usłyszycie o tym fabułę.

W 2021 roku w dużej mierze zakończymy proces projektowania, tworzenia i dostarczania tej architektury. Nazywamy ją RenderingNG, ponieważ to architektura renderowania nowej generacji, która znacznie przewyższa wcześniejsze porównanie. RenderingNG jest prowadzone od co najmniej 8 lat i jest wynikiem pracy wielu zaangażowanych programistów Chromium. Daje ogromne możliwości nowej generacji szybkich, płynnych, niezawodnych, elastycznych i interaktywnych treści internetowych. Moim zdaniem jest to również nowy minimalny standard dla wszystkich silników renderowania stron, na których mogą polegać deweloperzy.

Szkic różnych elementów RenderingNG
RenderingNG

To jest pierwszy post z naszej serii, w którym wyjaśniamy, co stworzyliśmy, dlaczego to zrobiliśmy i jak to działa. W tym pierwszym poście zacznę od:

  • Nasz cel gwiazdy północnej.
  • Piramida sukcesu: zasady, którymi kierujemy się w pracy, oraz przykłady ich stosowania w praktyce.
  • Funkcje i możliwości oferowane przez RenderingNG.
  • Ogólne omówienie głównych komponentów projektu RenderingNG.

Gwiazda Północna

Renderingiem jest to, że celem renderowania w przypadku gwiazdy północnej jest to, że implementacja mechanizmu przeglądarki ani bogactwo interfejsów API renderowania nie powinno być czynnikiem ograniczającym UX w internecie.

Nie musisz się martwić o błędy w przeglądarce, które sprawią, że funkcje będą niestabilne lub zakłócą renderowanie strony.

Nie powinno być żadnych tajemniczych klifów związanych z wydajnością. Nie musisz też pomijać brakujących funkcji wbudowanych.

To powinno zadziałać.

Uważam, że RenderingNG to ogromny krok w kierunku celu tej gwiazdy północnej. Przed usługą RenderingNG mogliśmy (i dokonaliśmy) dodać funkcje renderowania i poprawić wydajność. Mieliśmy jednak trudności z zapewnieniem niezawodności tych funkcji, a to z kolei wymagało sporo problemów z wydajnością. Teraz mamy architekturę, która systematycznie eliminuje wiele z tych problemów i pozwala odblokować zaawansowane funkcje, które wcześniej nie wydawały się możliwe. Oto one:

  • Ma niezwykle zaawansowane funkcje dostępne w kombinacjach różnych platform, urządzeń i systemów operacyjnych.
  • Zapewnia przewidywalną i niezawodną skuteczność.
  • Maksymalne wykorzystanie możliwości sprzętowych (rdzeń, GPU, rozdzielczości ekranu, częstotliwości odświeżania, niskopoziomowych interfejsów API rastrowych).
  • Umożliwia wykonywanie tylko tych czynności, które są potrzebne do wyświetlenia widocznej zawartości.
  • Ma wbudowaną obsługę typowych wzorców projektowania wizualnego, animacji i projektowania interakcji.
  • Zapewnia interfejsy API dla programistów, które ułatwiają zarządzanie kosztami renderowania.
  • Udostępnia punkty rozszerzenia potoku renderowania dla dodatków programisty.
  • Optymalizuje całą zawartość – HTML, CSS, kanwy 2D, obiekty canvas 3D, obrazy, filmy i czcionki.

Porównanie z innymi mechanizmami renderowania przeglądarki

Te same funkcje architektoniczne opisane w tych postach zostały wdrożone również w Gecko i Webkit, a w niektórych przypadkach nawet przed Chromium. co jest ekstra! Każda przeglądarka, która działa szybciej i jest bardziej niezawodna, jest powodem do świętowania i ma prawdziwy wpływ na skuteczność. Ostatecznym celem jest udoskonalenie standardu wszystkich przeglądarek, aby deweloperzy mogli na nich polegać.

Piramida sukcesu

Zgodnie z moją filozofią sukces wynika z uzyskania najpierw niezawodności, potem skalowalności, a w końcu rozszerzania.

Piramida z etykietami Niezawodność u podstaw, Wydajność pośrodku, możliwości rozszerzania

Podobnie jak w przypadku prawdziwej piramidy, każdy poziom stanowi solidną podstawę dla kolejnego poziomu.

Niezawodność

Szkic pokazujący, jak można dodawać funkcje RenderingNG bez większego frustracji

Jeśli w ogóle ma być możliwe tworzenie bogatych i złożonych wrażeń użytkownika, potrzebujemy solidnej platformy. Główne funkcje i podstawy muszą działać prawidłowo i nieustannie działać. Równie ważne jest, aby funkcje te składały się prawidłowo, aby nie wystąpiły w nich dziwne, skrajne wielkości liter ani błędy.

Sketch pokazuje cykliczny charakter dodawania funkcji, uzyskiwania opinii i poprawy niezawodności

Dlatego najważniejszą częścią usługi RenderingNG jest niezawodność. Niezawodność wynika z dobrych testów, pętli informacji zwrotnych o jakości, danych i wzorców projektowania oprogramowania.

Żeby dać wyobrażenie o tym, jak ważna jest moim zdaniem niezawodność, przez ostatnie 8 lat spędziliśmy większość prac na tej części. Po pierwsze, zgromadziliśmy dogłębną wiedzę o systemie – uczyliśmy się na podstawie raportów o błędach i naprawiając ich słabe punkty, uruchamialiśmy kompleksowe testy oraz poznaliśmy potrzeby związane z wydajnością witryn i ograniczenia działania Chromium. Następnie starannie i stopniowo zaprojektowaliśmy i wdrożyliśmy kluczowe wzorce projektowe oraz struktury danych. Dopiero wtedy byliśmy gotowi dodać zupełnie nową generację modeli podstawowych, które umożliwiają elastyczne projektowanie, skalowalność i dostosowywanie renderowania.

Szkicowany wykres pokazuje poprawę niezawodności, wydajności i elastyczności w miarę upływu czasu

Nie oznacza to, że nie wprowadziliśmy żadnych ulepszeń w Chromium na przestrzeni czasu. Wręcz przeciwnie! Te lata przynosiły stabilny i stały wzrost niezawodności i wydajności w miarę refaktoryzacji i wdrażania każdego ulepszenia krok po kroku.

Testowanie i dane

W ciągu ostatnich 8 lat dodaliśmy dziesiątki tysięcy testów jednostkowych, wydajności i integracji. Opracowaliśmy też kompleksowe dane mierzące wiele aspektów tego, jak renderowanie w Chromium działa w testach lokalnych, testach porównawczych wydajności i w rzeczywistych witrynach z udziałem prawdziwych użytkowników i urządzeń.

Bez względu na to, jak świetny jest RenderingNG (lub w innej przeglądarce silnik renderowania innej przeglądarki), w dalszym ciągu nie będzie łatwo opracować go dla stron internetowych, jeśli będzie wiele błędów lub różnic w działaniu między przeglądarkami. Aby rozwiązać ten problem, w pełni korzystamy też z testów platformy internetowej. Każdy z tych testów sprawdza wzorzec użytkowania platformy internetowej, do którego powinna dążyć wszystkie przeglądarki. Dokładnie monitorujemy też dane pod kątem przeprowadzania większej liczby testów w czasie i zwiększania głównej zgodności.

Testy platformy internetowej są wynikiem współpracy. Na przykład inżynierowie Chromium dodali tylko około 10% wszystkich testów WPT dotyczących funkcji CSS; pozostały dostawcy przeglądarek, niezależni współtwórcy i autorzy specyfikacji. Ta interoperacyjność wymaga całej wioski.

Testy zaliczone w różnych wyszukiwarkach
Od wpt.fyi/compat2021 mierzenie współczynnika zaliczonych WPT dla podstawowych funkcji

Dobre wzorce projektowania oprogramowania

O wiele łatwiej jest dostarczać oprogramowanie wysokiej jakości, jeśli kod jest łatwy do zrozumienia i zaprojektowany w sposób minimalizujący ryzyko wystąpienia błędów. W kolejnych postach na blogu napiszemy więcej o projektowaniu oprogramowania RenderingNG.

Skalowalna wydajność

Kolejnym ważnym aspektem RenderingNG jest osiągnięcie wysokiej wydajności w zakresie szybkości, pamięci i zużycia energii. Chcemy, aby interakcje ze wszystkimi witrynami odbywały się płynnie i szybko, ale bez negatywnego wpływu na stabilność urządzenia.

Nie zależy nam jednak tylko na wydajności – zależy nam na skalowalnej wydajności – czyli architektury, która działa niezawodnie na komputerach niskiej i wysokiej klasy oraz na różnych platformach operacyjnych. Nazywamy to skalowaniem w górę – wykorzystanie wszystkich możliwości urządzenia i skalowanie w dół – maksymalizację wydajności i ograniczanie zapotrzebowania na system w razie potrzeby.

Aby go osiągnąć, musieliśmy maksymalnie wykorzystać buforowanie, izolację wydajności oraz akcelerację sprzętową GPU. Omówmy każdą z nich po kolei. Aby było to zwięźle, zastanówmy się nad tym, jak każdy z nich wpływa na skuteczność jednej niezwykle ważnej interakcji na stronach internetowych, czyli przewijania.

Zapisywanie w pamięci podręcznej

W przypadku dynamicznej, interaktywnej platformy interfejsu, takiej jak internet, zapisywanie w pamięci podręcznej jest najważniejszym sposobem na znaczne zwiększenie skuteczności. Najbardziej znanym rodzajem buforowania w przeglądarce jest pamięć podręczna HTTP, ale renderowanie obejmuje też wiele pamięci podręcznych. Najważniejszą pamięcią podręczną do przewijania są tekstury GPU przechowywane w pamięci podręcznej i listy wyświetlania, które umożliwiają niezwykle szybkie przewijanie, minimalizując jednocześnie obciążenie baterii i działanie na różnych urządzeniach.

Pamięć podręczna pomaga wydłużyć czas pracy na baterii i liczbę klatek animacji przy przewijaniu, ale jeszcze ważniejsze jest to, że eliminuje izolację wydajności od wątku głównego.

Izolacja wydajności

Na nowoczesnych komputerach nie trzeba się martwić, że aplikacje działające w tle będą spowalniać bieżącą pracę. Wynika to z wyprzedzenia wielozadaniowości, która z kolei jest rodzajem izolacji wydajności i dba o to, aby niezależne zadania nie spowalniały się nawzajem.

W internecie najlepszym przykładem izolacji wydajności jest przewijanie. Nawet w witrynach z dużą ilością wolnego kodu JavaScript przewijanie może być bardzo płynne, ponieważ działa w innym wątku, który nie zależy od JavaScriptu i wątku układu. W RenderingNG wkładamy mnóstwo wysiłku, aby mieć pewność, że każdy przewijany tekst jest złożony z wątków, przez buforowanie, które wykracza daleko poza listę wyświetlania i w bardziej złożonych sytuacjach. Może to być na przykład kod reprezentujący stałe i przyklejone elementy, pasywne detektory zdarzeń oraz wysokiej jakości renderowanie tekstu.

Sketch pokazuje, że przy funkcji RenderingNG wydajność jest na stałym poziomie nawet wtedy, gdy JavaScript działa bardzo wolno.

Przyspieszenie GPU

Procesor GPU znacznie przyspiesza generowanie pikseli i rysowanie na ekranie – w wielu przypadkach każdy piksel można narysować równolegle do pozostałych pikseli, co znacznie zwiększa prędkość. Kluczowym komponentem RenderingNG jest rastrowanie GPU i rysowanie wszędzie. W tym przypadku wykorzystuje się GPU na wszystkich platformach i urządzeniach w celu nadmiernego przyspieszenia renderowania i animowania treści internetowych. Jest to szczególnie ważne w przypadku urządzeń słabszych i bardzo zaawansowanych, które często mają o wiele więcej GPU niż inne części urządzenia.

Sketch pokazuje, że przy RenderingNG wydajność nie zmniejsza się aż tak bardzo.

Większa elastyczność: odpowiednie narzędzia do konkretnego zadania

Po uzyskaniu niezawodności i skalowalnej wydajności możemy teraz korzystać z wielu narzędzi, które pomogą programistom rozbudować wbudowane części HTML, CSS i Canvas, bez uszczerbku dla tak żmudnej wydajności i niezawodności.

Obejmuje to wbudowane i eksponowane interfejsy API w języku JavaScript do zaawansowanych przypadków użycia elastycznego projektowania, renderowania progresywnego, płynności i responsywności oraz renderowania w wątkach.

Opisane poniżej otwarte internetowe interfejsy API, wspierane przez Chromium, powstały dzięki RenderingNG i do tej pory były uznawane za niewykonalne.

Wszystkie zostały opracowane przy otwartych specyfikacjach i we współpracy z otwartymi partnerami internetowymi, czyli inżynierami z innych przeglądarek, ekspertami i programistami stron internetowych. W kolejnych postach na blogu omówimy każdy z nich i wyjaśnimy, jak umożliwia je RenderingNG.

  • content-visibility: witryny mogą łatwo unikać renderowania treści poza ekranem i renderować w pamięci podręcznej w przypadku niewyświetlanych obecnie widoków aplikacji na jednej stronie.
  • OffscreenCanvas: umożliwia renderowanie kanw (zarówno interfejsu API kanw 2D, jak i WebGL) w oddzielnym wątku, co zapewnia doskonałą wydajność. Ten projekt to także kolejny ważny etap rozwoju internetu – pierwszy internetowy interfejs API, który pozwala JavaScript (lub WebAssembly!) na renderowanie pojedynczego dokumentu strony internetowej z wielu wątków.
  • Zapytania o kontenery: umożliwia responsywne rozmieszczanie elementów pojedynczego komponentu, co odblokowuje cały wszechświat komponentów Plug & Play (obecnie jest to implementacja eksperymentalna).
  • Izolacja źródeł: umożliwia witrynom lepszą izolację wydajności między elementami iframe.
  • Worklety malowane poza głównym wątkiem: umożliwiają programistom rozszerzenie sposobu malowania elementów za pomocą kodu uruchamianego w wątku kompozytora.

Oprócz jawnych internetowych interfejsów API, funkcja RenderingNG pozwoliła nam udostępnić kilka bardzo ważnych „funkcji automatycznych”, z których korzystają wszystkie witryny:

  • Izolacja witryn: umieszcza elementy iframe z innych domen w różnych procesach procesora, aby zwiększyć bezpieczeństwo i izolację wydajności.
  • Vulkan, D3D12 i Metal: wykorzystuje interfejsy API niższego poziomu, które wykorzystują GPU bardziej wydajnie niż OpenGL.
  • Więcej skomponowanych animacji: SVG, kolor tła.

Kolejne funkcje, które zostaną odblokowane przez RenderingNG, to m.in.:

Kluczowe projekty wchodzące w skład RenderingNG

Poniżej znajdziesz listę kluczowych projektów w RenderingNG. W kolejnych postach na blogu będziemy szczegółowo omawiać każdy z nich.

CompositeAfterPaint

Pozwala rozdzielić komponowanie od stylu, układu i renderowania, co umożliwia znacznie większą niezawodność i przewidywalną wydajność, większą przepustowość i zużywanie mniej pamięci bez negatywnego wpływu na wydajność. Rozpoczęła się w 2014 roku, a zakończy się w tym roku.

Rok Postęp
2015 Listy wyświetlania statków.
2017 Wyślij nowe unieważnienie.
2018 Drzewa właściwości statków, część 1.
2019 Drzewa właściwości statków, część 2.
2021 Przesłano projekt.

LayoutNG

Odrestaurowanie wszystkich algorytmów układu w celu znacznie większej niezawodności i przewidywalnej wydajności. Zaczęła się w 2016 roku, a zakończy się w tym roku.

Rok Postęp
2019 Przepływ bloku statku.
2020 Elastyczność statku, edycja.
2021 Wyślij pozostałe produkty.

BlinkNG

Systematyczne czyszczenie i refaktoryzacja silnika renderowania Blink na wyraźnie oddzielone fazy potoku. Pozwala to na lepsze buforowanie i zwiększanie niezawodności oraz umożliwia korzystanie z funkcji ponownego logowania lub renderowania z opóźnieniem, np. związanych z widocznością treści i zapytaniami o kontenery. Rozpoczęła się w 2014 roku i jest nieustannie ulepszana. Ukończy się w 2021 roku.

Przyspieszenie GPU w dowolnym miejscu

Długoterminowe wdrażanie rasteryzacji GPU, rysowania i animacji na wszystkich platformach przez cały czas. Przyspieszenie GPU znacznie przyspiesza większość treści, ponieważ każdy piksel może być przetwarzany równolegle. Jest to również skuteczna metoda poprawy wydajności na słabszych urządzeniach, które zazwyczaj nadal mają procesor graficzny. Program rozpoczął się w 2014 roku, a zakończył się w 2020 roku.

Rok Postęp
2014 Obsługa Canvas. Wysłano w przypadku treści, które wymagają zgody użytkownika na urządzeniach z Androidem.
2016 Wyślij na Macu.
2017 GPU jest wykorzystywane w ponad 60% wyświetleń stron na urządzeniach z Androidem.
2018 Wysyłaj produkty na urządzeniach z systemem Windows, ChromeOS i Android Go.
2019 Rasteryzacja GPU w wątkach.
2020 Wyślij pozostałe treści na Androida.

Przewijanie w wątkach, animacje i dekodowanie

Długoterminowe wysiłki związane z usunięciem wszystkich przewijanych, niewymagających układu animacji i dekodowania obrazów z wątku głównego. Program rozpoczął się w 2011 roku i cały czas trwa.

Rok Postęp
2011 Wstępna obsługa przewijania i animacji w wątkach.
2015 Ściskanie warstw.
2016 Uniwersalne przewijanie rozszerzone.
2017 Dekodowanie obrazu w wątku kompozytora.
2018 Animacje obrazów w wątku kompozytora.
2020 Zawsze o stałej pozycji.
2021 Procentowe animacje przekształcania, animacje SVG.

Wiz

Scentralizowany proces rastrowania i rysowania w Chromium, który zwiększa przepustowość, optymalizuje pamięć i umożliwia optymalne wykorzystanie możliwości sprzętu. Ma też inne zalety, które są mniej widoczne dla programistów stron internetowych, ale bardzo widoczne dla użytkowników, takie jak odblokowanie izolacji witryn i odłączenie potoku renderowania od renderowania interfejsu przeglądarki. Rozpoczął się w 2016 roku, a zakończy w 2021 roku.

Rok Postęp
2018 Usługa OOP-R została wysłana na urządzenia z Androidem, Mac i Windows.
2019 Wysłano zamówienie OOP-D. Dostawa OOP-R wszędzie (z wyjątkiem Canvas). System SkiaRenderer został udostępniony na urządzeniach z Linuksem.
2020 System SkiaRenderer został udostępniony na urządzeniach z systemem Windows i Androidem. Interfejs Vulkan dostępny na Androidzie.
2021 Usługa SkiaRenderer została wprowadzona na komputery Mac (a wkrótce także na ChromeOS).

Definicje terminów na wykresie powyżej:

Ups
Kompozytor wyświetlania poza procesem. Komponowanie wyświetlacza to ten sam rodzaj działania co kompozytor systemu operacyjnego. Awaria procesu oznacza zrobienie tego w procesie Viz, a nie w procesie renderowania strony internetowej lub w interfejsie przeglądarki.
OOP-R
Rastru poza procesem. Raster konwertuje listy wyświetlania na piksele. Awaria procesu oznacza jej realizację w procesie Viz, a nie w procesie renderowania strony internetowej.
SkiaRenderer
Nowa implementacja kompozytora reklam displayowych, która obsługuje wykonywanie kodu z wykorzystaniem różnych podstawowych interfejsów API GPU, takich jak Vulkan, D3D12 czy Metal.

Przyspieszone renderowanie kanw z wątkami i przyspieszonym renderowaniem

To projekt, dzięki któremu powstały elementy architektury, które umożliwiły stworzenie OffscreenCanvas. Rozpoczął się w 2015 roku, a zakończy w 2021 roku.

Rok Postęp
2018 Wyślij pozaekranowekanwy.
2019 Ship ImageBitmapRenderingContext.
2021 Wyślij OOP-R.

VideoNG

Długoterminowe działania mające na celu skuteczne, niezawodne i wysokiej jakości odtwarzanie filmów w internecie.

Rok Postęp
2014 Wprowadziliśmy platformę renderowania opartą na Mojo.
2015 Wysłano Project Butter i nakładki wideo, by zapewnić płynniejsze renderowanie filmów.
2016 Przesłano ujednolicone potoki dekodowania i renderowania Androida i komputerów.
2017 Przesłano HDR i renderowanie filmów z korygowaniem kolorów.
2018 Wysłano potok dekodowania wideo oparty na Mojo.
2019 Wysłano potok renderowania wideo na powierzchni.
2021 Wysłano obsługę renderowania treści chronionych w 4K w ChromeOS.

Definicje terminów na wykresie powyżej:

mojo
Podsystem IPC nowej generacji dla Chromium.
Platforma
Koncepcja wchodząca w skład projektu Viz.

Podsumowanie

Jestem niezmiernie podekscytowany wzrostem tempa renderowania w internecie i Chromium. Spodziewam się, że w nadchodzących latach tempo będzie coraz szybsze, ponieważ będziemy mogli tworzyć oparte na solidnych podstawach RenderingNG.

W kolejnych wpisach będziemy regularnie publikować posty ze szczegółowymi informacjami o nowej architekturze, sposobie jej powstania i działaniu.

Zdjęcie urządzeń: Eirik Solheim, Unsplash

Ilustracje: Una Kravets.