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. Druga optymalizacja, którą omówimy, to kluczowe wbudowanie kodu CSS, które jest obecnie domyślnie włączone w interfejsie wiersza poleceń Angular i jest obecnie w trakcie wdrażania w Nxt.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, jak to wygląda 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 ładowania aplikacji przeglądarka musi najpierw pobrać oryginalny arkusz stylów, do którego odwołuje się plik nagłówka.

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 ds. platformy wdrażają optymalizację w podstawowym narzędziu, ułatwiają korzystanie z tej funkcji zarówno w istniejących, jak i nowych aplikacjach, co przynosi ulepszenia w całym ekosystemie.

Ta funkcja jest domyślnie włączona w wersji Next.js 10.2 i Angular 11. Oba rozwiązania obsługują wstawianie 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) przez 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 Odrzuć niekrytyczne pliki CSS.

Zauważyliśmy, że wiele aplikacji wczytuje style synchronicznie, co blokuje renderowanie aplikacji. 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 zmień wartość atrybutu na all:

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

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

Strona migoczy podczas wczytywania stylów.

Na filmie powyżej widać, jak renderuje się strona, 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. Po znalezieniu dopasowania traktuje odpowiednie style jako część krytycznego kodu CSS i je wbudowuje.

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. W końcu zwierzaki wbudują odpowiednie style w sekcji <head> na stronie, co spowoduje:

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 korzystasz z wersji 11, włącz ją, ustawiając właściwość inlineCritical na true w narzędziu angular.json. Aby włączyć tę funkcję w Next.js, dodaj experimental: { optimizeCss: true } do next.config.js.

Podsumowanie

W tym poście omówiliśmy współpracę Chrome z ramami sieciowymi. Jeśli jesteś autorem koncepcji i wiesz, z jakimi problemami poruszyliśmy się w przypadku Twojej technologii, mamy nadzieję, że nasze wnioski zainspirują Cię do zastosowania podobnych metod optymalizacji wydajności.

Więcej informacji o ulepszeniach Pełna lista prac optymalizacji, które podjęliśmy w związku z podstawowymi wskaźnikami internetowymi, znajdziesz w artykule Przedstawiamy Aurora.