Nowy Firefox uruchomi gry i aplikacje webowe tak szybko, jakby ładował obrazki

Po długich latach zmagań między rozwiązaniami mającymipozwolić na jak najszybsze uruchamianie aplikacji w przeglądarkach,w 2015 roku wyłonił się standard WebAssembly.Definiuje on binarny format plików .wasm i odpowiadający muźródłowy format tekstowy kodu przypominającego assembler. Kodtaki uruchamiany jest na przenośnej maszynie stosowej, z szybkościąbliską szybkości natywnego kodu, w bezpiecznym sandboksie, poprzejściu formalnej weryfikacji. Co najważniejsze, obecniewszystkie najważniejsze przeglądarki są już w stanie uruchamiaćaplikacje dostarczane w postaci plików .wasm, a pod względemmożliwości aplikacje te mogą to samo, co aplikacje w JavaScripcie.Każdy z producentów ma jednak własną implementację standardu, aróżnią się one między innymi wydajnością dekodowania binarnychplików i ich kompilacji. Różnice były jednak niewielkie – ażdo teraz. Mozilla znalazła sposób, by radykalnie przyspieszyć tenproces.

Nowy Firefox uruchomi gry i aplikacje webowe tak szybko, jakby ładował obrazki

18.01.2018 12:48

WebAssembly a JavaScript

Silniki JavaScriptu osiągnęły granice możliwej optymalizacji.Pewnych rzeczy nie da się przeskoczyć. Przeglądarka pobierająckod w JavaScripcie pobiera go w formie tekstowej (nawet jeśli skryptzostał zminimalizowany). Potem parser musi przetworzyć go w drzewoskładni abstrakcyjnej, czyli rozpisanie logiki kodu na węzłypołączone według znaczących konstrukcji i składowych. Parseryrobią to zwykle po łebkach, przetwarzając tylko te funkcje, którezostaną zaraz bezpośrednio wywołane, a zamiast reszty wstawiającstuby (czyli puste obiekty). Finalnie takie drzewo składniowezostaje przekształcone na bajtowy kod pośredniczący, któryprzechodzi swoje wstępne procesy optymalizacji, a następnie jesturuchomiany i jednocześnie optymalizowany w trakcie uruchomienia nasilniku skryptowym tej konkretnej przeglądarki.

W wypadku WebAssembly sytuacja wygląda znacznie prościej.Przeglądarka dostaje zwarty kod pośredniczący w binarnej postaci.Musi on zostać jedynie zdekodowany (jest to nawet 20 razy szybsze odparsowania) i sprawdzony pod kątem błędów, potem zostajeskompilowany i uruchomiony. Sam proces kompilacji zależy odprzeglądarki, ale tak czy inaczej jest o wiele wydajniejszy, choćbyze względu na statyczną typizację (jak np. w C/C++) i to, że kodWebAssembly jest efektem pracy kompilatora, a nie człowieka. Wefekcie aplikacja WebAssembly nie tylko ładuje się znaczącoszybciej, ale też działa później w przeglądarce o wielewydajniej.

Oczywiście celem WebAssembly nie jest zastąpienie JavaScriptu,raczej jego uzupełnienie – chodzi o danie programistom lepszejplatformy do uruchamiania złożonych, wymagających aplikacji,pisanych przede wszystkim w C/C++, a nie sterowanie w tym językuinterfejsami użytkownika stron internetowych.

Wyścigi na nowym torze

Wydajność silników JavaScriptu wiodących przeglądarek jestdziś zbliżona. Można powiedzieć że są benchmarki, w którychwygra Chrome, są takie, które pokażą wyższość Firefoksa, znająsię nawet takie, w których najlepsze będzie Edge. W wypadkuWebAssembly, które stało się po prostu częścią tych silnikówskryptowych (wykorzystywane są istniejący backend kompilatora,mechanizmy sandboksa, frontend ładowania modułów itp.) teżróżnice nie było wielkie.

Na łamach blogaMozilli, pani Lin Clark opisuje jednak nowe metody ładowania ikompilowania kodu WebAssembly, które uczynią z Firefoksa58 najszybszą platformę do uruchamiania takich aplikacji. Niemówimy tu o wzrostach rzędu kilku-kilkunastu procent. Jaksprawdziliśmy na kompilacji nightly Firefoksa, mowa okilkunastokrotnym przyspieszeniu. Innymi słowy, Mozilla zmieniłareguły gry. Nagle okazuje się, że kod w pliku .wasm jestprzetwarzany szybciej, niż ładowany przez sieć, innymi słowy,przypomina bardziej bitmapowy obrazek niż kod w JavaScripcie. Do tejpory skrypt, który miał 100 KB, był uważany za duży skrypt, zaśobrazek mający 100 KB był w sumie niedużym obrazkiem. Teraz 100 KBskrypt WebAssembly musimy uznać również za nieduży.

Obraz

Jak ten nowy kompilator działa? Przede wszystkim rozpoczynakompilację wcześniej, nie czekając na pobranie całego pliku.Kompiluje kod WebAssembly linijka po linijce, jakby było to jakieśstrumieniowane medium (właściwie to jest, za sprawą specjalnegointerfejsu do strumieniowania kodu). A jako że sekcja kodu w plikubinarnym jest przed sekcją danych, kod do wykonania może byćgotowy na długo przed pobraniem pliku. Tak pobierane obiekty .wasmmogą być oczywiście kompilowane równolegle.

Kompilacja WebAssebmbly w Firefoksie 57
Kompilacja WebAssebmbly w Firefoksie 57

Do tego dochodzą nowe techniki optymalizacji. InżynierowieMozilli mówią o warstwowym (tiered) kompilatorze. Gdy kod zaczynanapływać wartkim strumieniem, kompilowany jest przed podstawowykompilator (Tier 1). Gdy kod ten zostaje uruchomiony i już działa,włącza się drugi kompilator, korzystający z zaawansowanychtechnik optymalizacji, w tle ponownie sobie kompiluje cały kod ipodmienia pierwotną wersję na tę bardziej zoptymalizowaną. Wefekcie aplikacja po chwili od uruchomienia przyspiesza.

Kompilacja WebAssembly w Firefoksie Nightly (59)
Kompilacja WebAssembly w Firefoksie Nightly (59)

Taki podział ma sens z perspektywy tego, co dostrzega użytkownik– kompilator Tier 1 jest dziesięciokrotnie szybszy od kompilatoraTier 2, a zarazem generuje dwukrotnie wolniejszy kod. Wartopodkreślić, że oba kompilatory korzystają ze wszystkichdostępnych rdzeni procesora. Efekt można zobaczyć w prostymbenchmarku Mozilli, mierzącym czas kompilacji gryTanks.

Kompilacja WebAssembly w Google Chrome 61
Kompilacja WebAssembly w Google Chrome 61

To nie koniec możliwości optymalizacji: Mozilla zamierza wnastępnym etapie wprowadzić bufor dla już skompilowanego kodu. Poco ciągle kompilować te same pliki .wasm? Po otworzeniu stronyinternetowej z tym samym kodem, od razu dostaniemy w przeglądarceprekompilowany kod maszynowy. To naprawdę świt nowej ery dlazaawansowanych aplikacji webowych.

Użyteczne linki

Źródło fotografii Red fox with an egg – Flickr, autor: Nora Feddal licencja: CC BY-SA 2.0

Programy

Zobacz więcej
Wybrane dla Ciebie
Komentarze (54)