Wbudowanie zasobów w platformy JavaScript

Ulepszanie największego wyrenderowania treści w ekosystemie JavaScriptu.

W ramach projektu Aurora współpracujemy z popularnymi platformami internetowymi, aby zapewnić ich prawidłowe działanie zgodnie z podstawowymi wskaźnikami internetowymi. W Angular i Next.js są już wbudowane czcionki. Zostało to opisane w pierwszej części tego artykułu. Druga optymalizacja, którą omówimy, to kluczowa inicjacja CSS, która jest teraz domyślnie włączona w interfejsie wiersza poleceń Angular i jest w trakcie implementacji w Nuxt.js.

Wbudowanie czcionki

Po przeanalizowaniu setek aplikacji zespół Aurora odkrył, że programiści często umieszczają w swoich aplikacjach czcionki, odwołując się do nich w elemencie <head> w elemencie index.html. Oto przykład, jak wyglądałoby to w przypadku dodania ikon Material Design:

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

Mimo że ten wzorzec jest całkowicie prawidłowy i funkcjonalny, blokuje renderowanie aplikacji i wysyła dodatkowe żądanie. Aby lepiej zrozumieć, co się dzieje, przyjrzyj się kodowi źródłowemu arkusza stylów, do którego odwołuje się kod HTML powyżej:

/* 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 w fonts.gstatic.com. Podczas wczytywania aplikacji przeglądarka musi najpierw pobrać pierwotny arkusz stylów, do którego odwołuje się nagłówek.

Obraz pokazujący, jak witryna musi wysł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 i w końcu może kontynuować renderowanie aplikacji.

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

Możliwość optymalizacji to pobranie początkowego arkusza stylów podczas kompilacji i wbudowanie go w index.html. Spowoduje to pominięcie całej komunikacji w obie strony do sieci CDN w czasie działania, co skraca czas blokowania.

Podczas tworzenia aplikacji do sieci CDN wysyłane jest żądanie, które powoduje pobranie arkusza stylów i umieszczenie go w pliku HTML oraz dodanie do domeny polecenia <link rel=preconnect>. Stosując tę technikę, 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>

Wbudowanie czcionki jest teraz dostępne w usługach Next.js i Angular

Gdy deweloperzy platformy wdrażają optymalizację w podstawowych narzędziach, ułatwiają one istniejących i nowych aplikacjom, co usprawnia cały ekosystem.

To ulepszenie jest domyślnie włączone w Next.js w wersji 10.2 i Angular w wersji 11. Obie obsługują wbudowanie czcionek Google i Adobe. Angular zamierza wprowadzić tę funkcję w wersji 12.2.

Implementację wstawianego czcionki w Next.js znajdziesz na GitHubie i obejrzyj film wyjaśniający tę optymalizację w kontekście Angular.

Wbudowanie krytycznego kodu CSS

Kolejne ulepszenie obejmuje poprawę danych Pierwsze wyrenderowanie treści (FCP) i największe wyrenderowanie treści (LCP) przez wbudowanie newralgicznego kodu CSS. Kluczowy kod CSS strony zawiera wszystkie style użyte przy początkowym renderowaniu. Aby dowiedzieć się więcej na ten temat, przeczytaj artykuł o odroczeniu niekrytycznych obszarów CSS.

Zauważyliśmy, że wiele aplikacji wczytuje style synchroniczne, co blokuje renderowanie aplikacji. W ramach szybkiego rozwiązania problemu możesz ładować style asynchronicznie. Zamiast ładować skrypty za pomocą media="all", ustaw wartość atrybutu media na print, a po zakończeniu wczytywania zastąp wartość atrybutu all:

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

Takie działanie może jednak powodować migotanie treści bez stylu.

Strona zaczyna migotać w miarę wczytywania stylów.

Powyższy film przedstawia renderowanie strony, która asynchronicznie wczytuje jej style. Migotanie pojawia się, ponieważ przeglądarka najpierw pobiera style, a potem renderuje kod HTML, który jest widoczny poniżej. Gdy przeglądarka pobierze style, wywoła zdarzenie onload elementu link, zaktualizuje atrybut media do wartości all i zastosuje style do modelu DOM.

W czasie między wyrenderowaniem kodu HTML a zastosowaniem stylów strona częściowo zmienia styl. Gdy przeglądarka użyje tych stylów, obserwujemy migotanie, co niekorzystnie wpływa na wygodę użytkowników i powoduje spadek skumulowanego przesunięcia układu (CLS).

Krytyczne wbudowanie kodu CSS wraz z asynchronicznym wczytywaniem stylu, może poprawić zachowanie wczytywania. Narzędzie critters określa, które style są używane na stronie, przeglądając selektory w arkuszu stylów i dopasowując je do kodu HTML. Gdy znajdzie dopasowanie, uwzględnia odpowiednie style jako część krytycznego kodu CSS i uwzględnia je w tekście.

Spójrzmy na 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 wbudowaniem.

W powyższym przykładzie stworzenia odczytują i analizują zawartość tagu styles.css, a potem dopasowuje on 2 selektory do kodu HTML i wykrywa, że używamy section button.primary. Na koniec zwierzaki umieszczają odpowiednie style w elemencie <head> strony, co daje:

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.

Po wbudowaniu krytycznego kodu CSS w kodzie HTML zauważysz, że migotanie strony zniknęło:

Strona wczytuje się po wczytaniu CSS.

Krytyczne wbudowanie kodu CSS jest teraz dostępne w Angular i domyślnie włączone w wersji 12. Jeśli używasz wersji 11, włącz ją w narzędziu angular.json, ustawiając 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 obszar współpracy między Chrome a platformami internetowymi. Jeśli tworzysz struktury i wiesz, jakie problemy rozwiązaliśmy w Twojej technologii, mamy nadzieję, że nasze ustalenia zainspirują Cię do wprowadzenia podobnych optymalizacji skuteczności.

Więcej informacji o ulepszeniach Pełną listę wypracowań optymalizacyjnych, które przeprowadziliśmy pod kątem podstawowych wskaźników internetowych, znajdziesz w poście Przedstawiamy Aurora.