Wbudowanie zasobów w platformy JavaScript

poprawa największego wyrenderowania treści w ekosystemie JavaScript;

W ramach projektu Aurora firma Google współpracowała z popularnymi frameworkami internetowymi, aby zapewnić ich dobrą wydajność zgodnie z podstawowymi wskaźnikami internetowymi. W Angular i Next.js wdrożone zostało już wstawianie czcionek, co zostało opisane w pierwszej części tego artykułu. Drugą optymalizacją, którą omówimy, jest wstawianie kluczowych reguł CSS, które są teraz domyślnie włączone w CLI Angulara i są w trakcie implementacji w Nuxt.js.

Wstawianie czcionki

Po przeanalizowaniu setek aplikacji zespół Aurora stwierdził, że deweloperzy często uwzględniają czcionki w swoich aplikacjach, odwołując się do nich w elemencie <head> w pliku index.html. Oto przykład tego, jak będzie wyglądać ikona z użyciem ikon Material Design:

<!doctype html>
<html lang="en">
<head>
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  ...
</html>

Chociaż ten wzór jest całkowicie prawidłowy i działa prawidłowo, blokuje renderowanie aplikacji i wywołuje dodatkową prośbę. Aby lepiej zrozumieć, co się dzieje, spójrz na kod źródłowy arkusza stylów, do którego odwołuje się kod HTML:

/* fallback */
@font-face {
  font-family: 'Material Icons';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/font.woff2) format('woff2');
}

.material-icons {
  /*...*/
}

Zwróć uwagę, że definicja font-face odwołuje się do pliku zewnętrznego hostowanego na serwerze fonts.gstatic.com. Podczas wczytywania aplikacji przeglądarka musi najpierw pobrać oryginalny arkusz stylów, do którego odwołuje się nagłówek.

Ilustracja pokazująca, jak witryna musi przesłać żądanie do serwera i pobrać zewnętrzny arkusz stylów
Najpierw witryna wczytuje arkusz stylów czcionki.

Następnie przeglądarka pobiera plik woff2, a na koniec może przejść do renderowania aplikacji.

Obraz pokazujący 2 wysłane żądania: jedno dotyczące arkusza stylów czcionki, a drugie – pliku czcionki.
Następnie wysyłane jest żądanie załadowania czcionki.

Możliwość optymalizacji polega na pobraniu początkowej sekcji stylów w momencie kompilacji i wstawieniu jej w elementie index.html. Dzięki temu nie trzeba wykonywać całego procesu przesyłania i odbierania danych do CDN w czasie wykonywania kodu, co skraca czas blokowania.

Podczas kompilowania aplikacji wysyłane jest żądanie do sieci CDN, która pobiera arkusz stylów i umieszcza go w pliku HTML, dodając do domeny <link rel=preconnect>. Po zastosowaniu tej techniki otrzymamy taki wynik:

<!doctype html>
<html lang="en">
<head>
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin >
  <style type="text/css">
  @font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/font.woff2) format('woff2');}.material-icons{/*...*/}</style>
  ...
</html>

Wstawianie czcionek jest teraz dostępne w Next.js i Angular

Gdy deweloperzy frameworków implementują optymalizację w podstawowych narzędziach, ułatwiają wdrożenie tej funkcji w dotychczasowych i nowych aplikacjach, co przynosi korzyści całemu ekosystemowi.

Ta funkcja jest domyślnie włączona w wersji Next.js 10.2 i Angular 11. Oba rozwiązania obsługują wklejanie czcionek Google i Adobe. Angular planuje wprowadzić tę funkcję w wersji 12.2.

Implementację wstawiania czcionek w Next.js znajdziesz na GitHubie. Możesz też obejrzeć film, który wyjaśnia tę optymalizację w kontekście Angulara.

Wstawianie kluczowych arkuszy CSS

Kolejnym ulepszeniem jest poprawa wskaźników pierwszego wyrenderowania treści (FCP)największego wyrenderowania treści (LCP) poprzez wstawienie kodu CSS do kodu źródłowego. Krytyczny plik CSS strony zawiera wszystkie style używane podczas początkowego renderowania. Więcej informacji na ten temat znajdziesz w artykule Opóźnianie wczytywania nieistotnych plików CSS.

Zauważyliśmy, że wiele aplikacji wczytuje style synchronicznie, co blokuje ich renderowanie. Szybkim rozwiązaniem jest wczytywanie stylów w tle. Zamiast wczytywać skrypty za pomocą atrybutu media="all", ustaw wartość atrybutu media na print, a po zakończeniu wczytywania zastąp tę wartość atrybutem all:

<link rel="stylesheet" href="..." media="print" onload="this.media='all'">

Może to jednak spowodować migotanie treści bez stylizacji.

Strona migocze podczas wczytywania stylów.

Film powyżej pokazuje renderowanie strony, która wczytuje style asynchronicznie. Migotanie występuje, ponieważ przeglądarka najpierw pobiera style, a potem renderuje kod HTML. Gdy przeglądarka pobierze style, uruchamia zdarzenie onload elementu link, aktualizując atrybut media na all, i zastosuje style do DOM.

W czasie między renderowaniem kodu HTML a zastosowaniem stylów strona jest częściowo bez stylów. Gdy przeglądarka używa stylów, występuje migotanie, które nie jest przyjazne użytkownikom i powoduje regresję skumulowanego przesunięcia układu (CLS).

Wbudowanie krytycznego kodu CSS wraz z asynchronicznym wczytywaniem stylów może poprawić działanie wczytywania. Narzędzie critters wykrywa, które style są używane na stronie, przez analizowanie selektorów w arkuszu stylów i porównywanie ich z kodem HTML. Gdy znajdzie dopasowanie, uznaje odpowiednie style za część krytycznego kodu CSS i umieszcza je w kodzie strony.

Przeanalizujmy poniższy przykład:

Nie
<head>
   <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
</head>
<body>
  <section>
    <button class="primary"></button>
  </section>
</body>
/* styles.css */
section button.primary {
  /* ... */
}
.list {
  /* ... */
}

Przykład przed wstawieniem.

W przypadku tego przykładu skrypt odczytuje i przeanalizuje zawartość pliku styles.css, a potem dopasuje 2 selektory do kodu HTML i sprawdzi, czy używamy section button.primary. Na koniec funkcja critters wstawia odpowiednie style w <head> strony, co powoduje:

Tak
<head>
  <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
  <style>
  section button.primary {
    /* ... */
  }
  </style>
</head>
<body>
  <section>
    <button class="primary"></button>
  </section>
</body>

Przykład po wstawieniu kodu.

Po wstawieniu kodu CSS w kodzie HTML miganie strony zniknie:

Załadowanie strony po wstawieniu kodu CSS.

Wstawianie kluczowych reguł CSS jest teraz dostępne w Angularze i domyślnie włączone w wersji 12. Jeśli używasz wersji 11, włącz tę funkcję, ustawiając w elementach angular.jsoninlineCritical właściwość inlineCritical na true. Aby włączyć tę funkcję w Next.js, dodaj experimental: { optimizeCss: true } do next.config.js.

Podsumowanie

W tym poście omówiliśmy niektóre aspekty współpracy Chrome z ramami internetowymi. Jeśli jesteś autorem frameworka i rozpoznajesz niektóre z problemów, które rozwiązaliśmy w naszej technologii, mamy nadzieję, że nasze odkrycia zainspirują Cię do zastosowania podobnych optymalizacji wydajności.

Więcej informacji o ulepszeniach Pełną listę optymalizacji, które przeprowadziliśmy w przypadku podstawowych wskaźników internetowych, znajdziesz w artykule Prezentujemy Aurora.