Ćwiczenia z programowania: wstępne wczytywanie zasobów krytycznych, które pozwalają przyspieszyć wczytywanie

W tym laboratorium kodu poprawiamy wydajność tej strony internetowej, wczytując wstępnie kilka zasobów:

Zrzut ekranu aplikacji

Zmierz odległość

Zanim wprowadzisz jakiekolwiek optymalizacje, zmierz najpierw skuteczność witryny.

  • Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran pełny ekran.

Przeprowadź audyt wydajności Lighthouse (Lighthouse > Opcje > Wydajność) w wersji Glitch na żywo (zobacz też Znajdź możliwości poprawy wydajności za pomocą Lighthouse).

Lighthouse wyświetla następującą kontrolę z błędem w przypadku zasobu, który jest pobierany z opóźnieniem:

Lighthouse: audyt wstępnego wczytywania żądań kluczy
  • Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
  • Kliknij kartę Sieć.
Panel sieci z wykrytym późno zasobem

Plik main.css nie jest pobierany przez element Link (<link>) umieszczony w dokumencie HTML, ale przez oddzielny plik JavaScript (fetch-css.js), który dołącza element Link do DOM po zdarzeniu window.onLoad. Oznacza to, że plik jest pobierany dopiero po zakończeniu analizowania i wykonywania pliku JS przez przeglądarkę. Podobnie czcionka internetowa (K2D.woff2) określona w elementach main.css jest pobierana dopiero po zakończeniu pobierania pliku CSS.

Łańcuch żądań krytycznych to kolejność zasobów, które są priorytetowo pobierane przez przeglądarkę. W przypadku tej strony internetowej wygląda to tak:

├─┬ / (initial HTML file)
  └── fetch-css.js
    └── main.css
      └── K2D.woff2

Plik CSS znajduje się na trzecim poziomie łańcucha żądań, więc Lighthouse zidentyfikował go jako zasób odkryty późno.

Wstępne wczytywanie ważnych zasobów

Plik main.css to kluczowy zasób, który jest potrzebny natychmiast po załadowaniu strony. W przypadku ważnych plików, takich jak ten zasób, które są pobierane późno w aplikacji, użyj tagu wstępnego wczytywania linku, aby poinformować przeglądarkę o konieczności wcześniejszego pobrania pliku. W tym celu dodaj element Link do nagłówka dokumentu.

Dodaj tag wstępnego wczytania dla tej aplikacji:

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
</head>

Atrybut as służy do identyfikowania typu zasobu, który jest pobierany, a atrybut as="style" służy do wstępnego wczytania plików arkuszy stylów.

Załaduj ponownie aplikację i sprawdź panel Sieć w Narzędziach dla programistów.

Panel sieci z wstępnie załadowanym zasobem

Zwróć uwagę, że przeglądarka pobiera plik CSS, zanim skończy się analizowanie kodu JavaScript odpowiedzialnego za jego pobieranie. W przypadku wczytania wstępnego przeglądarka wie, że musi pobrać zasób z wyprzedzeniem, ponieważ jest on kluczowy dla strony internetowej.

Nieprawidłowe użycie funkcji wstępnego ładowania może obniżyć wydajność, ponieważ powoduje niepotrzebne żądania dotyczące nieużywanych zasobów. W tej aplikacji details.css to inny plik CSS znajdujący się w katalogu głównym projektu, ale używany do osobnego /details route. Aby pokazać przykład nieprawidłowego użycia funkcji wstępnego wczytania, dodaj do tego zasobu również podpowiedź dotyczącą wstępnego wczytania.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Załaduj ponownie aplikację i sprawdź panel Sieć. Żądanie pobrania elementu details.css jest wysyłane, mimo że nie jest on używany przez stronę internetową.

Panel sieci z niepotrzebnym wstępnym wczytaniem

Jeśli w ciągu kilku sekund po załadowaniu zasobów wstępnie załadowanych strona nie użyje ich, Chrome wyświetli ostrzeżenie w panelu Konsola.

Ostrzeżenie o wstępnym wczytaniu w konsoli

Użyj tego ostrzeżenia, aby sprawdzić, czy masz jakieś wstępnie załadowane zasoby, których Twoja strona internetowa nie używa od razu. Możesz teraz usunąć z tej strony niepotrzebny link do wstępnego wczytania.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Listę wszystkich typów zasobów, które można pobrać, wraz z prawidłowymi wartościami atrybutu as, znajdziesz w artykule MDN na temat wstępnego wczytywania.

Pobieranie w poprzednim planie zasobów, które będą potrzebne w przyszłości

Wstępne pobieranie to kolejny sygnał dla przeglądarki, który można wykorzystać do wysłania żądania zasobu używanego na innej ścieżce nawigacji, ale o niższym priorytecie niż inne ważne zasoby potrzebne na bieżącej stronie.

W tej witrynie kliknięcie obrazu powoduje przejście do osobnej details/trasy.

Szczegóły trasy

Oddzielny plik CSS (details.css) zawiera wszystkie style potrzebne do tej prostej strony. Dodaj element linku do index.html, aby z wyprzedzeniem pobrać ten zasób.

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

Aby dowiedzieć się, jak to powoduje żądanie pliku, otwórz panel Sieć w Narzędziach dla programistów i odznacz opcję Wyłącz pamięć podręczną.

Wyłączanie pamięci podręcznej w Narzędziach deweloperskich w Chrome

Ponownie załaduj aplikację i zwróć uwagę, że po pobraniu wszystkich innych plików wysyłane jest żądanie dotyczące pliku details.css o bardzo niskim priorytecie.

Panel sieciowy z zasobem wyprzedzającym

Gdy otwarte są Narzędzia deweloperskie, kliknij obraz w witrynie, aby przejść na stronę details. Ponieważ w elementie linka details.html używanym do pobierania zasobu details.css występuje element linka, żądanie dotyczące tego zasobu jest wysyłane zgodnie z oczekiwaniami.

Żądania sieciowe na stronie z informacjami

Aby wyświetlić szczegóły żądania sieciowego details.css, kliknij je w Narzędziach deweloperskich. Zauważ, że plik jest pobierany z pamięci podręcznej dysku przeglądarki.

Szczegóły żądania pobrane z pamięci podręcznej na dysku

Wykorzystując czas bezczynności przeglądarki, funkcja wstępnego pobierania wysyła wcześniej żądanie zasobu potrzebnego na innej stronie. Przyspiesza to przyszłe żądania nawigacji, ponieważ pozwala przeglądarce wcześniej wczytać zasób do pamięci podręcznej i w razie potrzeby wyświetlać go z pamięci podręcznej.

Wstępne ładowanie i pobieranie z wyprzedzeniem za pomocą webpack

W artykule Zmniejsz rozmiary ładunków JavaScript dzięki dzieleniu kodu znajdziesz informacje o używaniu importów dynamicznych do dzielenia pakietu na kilka fragmentów. Jest to demonstrowane za pomocą prostej aplikacji, która dynamicznie importuje moduł z Lodash po przesłaniu formularza.

Aplikacja Magic Sorter, która demonstruje dzielenie kodu

Tutaj możesz uzyskać dostęp do Glitcha tej aplikacji.

Ten blok kodu, który znajduje się w funkcji src/index.js,, odpowiada za dynamiczne importowanie metody po kliknięciu przycisku.

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

Podział pakietu poprawia czas wczytywania strony, ponieważ zmniejsza jego początkowy rozmiar. Wersja 4.6.0 pakietu webpack obsługuje wstępny wczytywanie lub wyprzedzające wczytywanie fragmentów, które są importowane dynamicznie. W ramach tej aplikacji można na przykład wstępnie pobrać metodę lodash, gdy przeglądarka jest nieaktywna. Gdy użytkownik naciśnie przycisk, zasób zostanie pobrany bez opóźnienia.

Aby pobrać wstępnie określony fragment, użyj w ramach importu dynamicznego parametru webpackPrefetch. Oto jak to wygląda w przypadku tej konkretnej aplikacji.

form.addEventListener("submit", e => {
  e.preventDefault()
  import(/* webpackPrefetch: true */ 'lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

Po ponownym załadowaniu aplikacji webpack wstrzykuje tag pobierania z wyprzedzeniem dla zasobu do nagłówka dokumentu. Możesz to sprawdzić w panelu Elementy w Narzędziach dla programistów.

Panel elementów z tagiem pobierania wstępnego

Obserwując żądania w panelu Sieć, możesz też zauważyć, że ten fragment jest pobierany z niskim priorytetem po przesłaniu wszystkich pozostałych zasobów.

Panel sieci z żądaniem pobierania w poprzednim etapie

Chociaż w tym przypadku bardziej przydatne jest pobieranie w poprzedniości, webpack obsługuje też wstępne pobieranie fragmentów, które są importowane dynamicznie.

import(/* webpackPreload: true */ 'module')

Podsumowanie

Po zakończeniu pracy z tym laboratorium kodu powinieneś/powinnaś dobrze rozumieć, jak wstępne wczytywanie lub wstępne pobieranie określonych zasobów może poprawić wrażenia użytkowników Twojej witryny. Należy pamiętać, że tych technik nie należy stosować w przypadku każdego zasobu, a nieprawidłowe ich użycie może pogorszyć wydajność. Najlepsze wyniki uzyskuje się, stosując tylko wczytywanie wstępne lub wczytywanie wstępne selektywnie.

Podsumowując:

  • Użyj wstępnego wczytania w przypadku zasobów, które są wykrywane późno, ale są kluczowe dla bieżącej strony.
  • Użyj wstępnego wczytania w przypadku zasobów potrzebnych do utworzenia przyszłej trasy nawigacji lub działania użytkownika.

Nie wszystkie przeglądarki obsługują zarówno wstępny, jak i wcześniejszy wstępny wczytywanie. Oznacza to, że nie wszyscy użytkownicy aplikacji mogą zauważyć poprawę wydajności.

Jeśli chcesz dowiedzieć się więcej o szczegółowych aspektach wpływu wstępnego wczytywania i wstępnego pobierania na stronę internetową, przeczytaj te artykuły: