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 bibliotekach 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 Material Icons:

<!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łana jest prośba o wczytanie 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ć pełnego połączenia z 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ą korzystanie z niej istniejącym i nowym aplikacjom, co przynosi korzyści całemu ekosystemowi.

Ta poprawka jest domyślnie włączona w wersji Next.js 10.2 i Angular 11. Oba formaty 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) poprzez wstawienie kodu CSS do kodu źródłowego. Krytyczny kod CSS strony obejmuje wszystkie style używane podczas jej początkowego renderowania. Aby dowiedzieć się więcej na ten temat, przeczytaj artykuł 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 niesynchroniczny sposób. 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 przyjemne dla użytkownika 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, analizując selektory w arkuszu stylów i porównując je 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 kodu inline

W przypadku tego przykładu robaki odczytają i przeanalizują zawartość styles.css, a potem dopasują 2 selektory do kodu HTML i stwierdzają, że używamy section button.primary. Na koniec Critter 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 zauważysz, że strona przestaje migać:

Przeglądanie strony po wstawieniu arkusza CSS.

Wstawianie kluczowych reguł CSS jest teraz dostępne w Angular 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 celu poprawy podstawowych wskaźników internetowych, znajdziesz w poście Wprowadzenie do Aurora.