Wstępnie wczytuj najważniejsze zasoby, aby przyspieszyć wczytywanie

Gdy otwierasz stronę internetową, przeglądarka wysyła do serwera żądanie dokumentu HTML, analizuje jej zawartość i przesyła osobne żądania dotyczące wszystkich przywoływanych zasobów. Jako programista wiesz już, które zasoby są niezbędne dla Twojej strony i które z nich są najważniejsze. Możesz wykorzystać tę wiedzę, aby z wyprzedzeniem poprosić o dostęp do kluczowych zasobów, co przyspieszy proces wczytywania. Z tego posta dowiesz się, jak to zrobić za pomocą <link rel="preload">.

Jak działa wstępne wczytywanie

Wstępne wczytywanie sprawdza się najlepiej w przypadku zasobów, które zwykle są wykrywane przez przeglądarkę później.

Zrzut ekranu przedstawiający panel Network (Sieć) w Chrome DevTools.
W tym przykładzie czcionka Pacifico jest zdefiniowana w arkuszu stylów za pomocą reguły @font-face. Przeglądarka wczytuje plik czcionek dopiero po zakończeniu pobierania i analizowania arkusza stylów.

Wstępnie wczytując jakiś zasób, informujesz przeglądarkę, że chcesz pobrać go szybciej, niż przeglądarka by wykryła, ponieważ masz pewność, że jest on ważny dla bieżącej strony.

Zrzut ekranu przedstawiający panel Network (Sieć) w Chrome DevTools po zastosowaniu wstępnego wczytywania.
W tym przykładzie czcionka Pacifico jest wstępnie wczytana, więc pobieranie odbywa się równolegle z arkuszem stylów.

Krytyczny łańcuch żądań reprezentuje kolejność zasobów, które są traktowane priorytetowo i pobierane przez przeglądarkę. Lighthouse identyfikuje zasoby na trzecim poziomie łańcucha jako wykryte późno. Aby określić, które zasoby mają być wstępnie wczytane, możesz skorzystać z kontroli wstępnego wczytywania żądań kluczy.

Audyt wstępnego ładowania żądań kluczy w Lighthouse.

Możesz wstępnie wczytywać zasoby, dodając w nagłówku dokumentu HTML tag <link> z elementem rel="preload":

<link rel="preload" as="script" href="critical.js">

Przeglądarka zapisuje w pamięci podręcznej wstępnie wczytane zasoby, aby były dostępne od razu, gdy są potrzebne. (Nie wykonuje on skryptów ani nie stosuje arkuszy stylów).

Wskazówki dotyczące zasobów, na przykład preconnect i prefetch, są wykonywane w zależności od potrzeb przeglądarki. Z kolei preload jest wymagany w przeglądarce. Współczesne przeglądarki dość dobrze radzą sobie z określaniem priorytetów zasobów, dlatego tak ważne jest oszczędne korzystanie z preload i wstępne wczytywanie tylko najważniejszych zasobów.

Nieużywane wstępne załadowania wywołują ostrzeżenie konsoli w Chrome około 3 sekund po zdarzeniu load.

Ostrzeżenie w konsoli Narzędzi deweloperskich w Chrome dotyczące nieużywanych wstępnie załadowanych zasobów.

Przykłady zastosowań

Wstępne wczytywanie zasobów zdefiniowanych w CSS

Czcionki zdefiniowane za pomocą reguł @font-face lub obrazy tła zdefiniowane w plikach CSS nie zostaną wykryte, dopóki przeglądarka nie pobierze i przeanalizuje tych plików CSS. Wstępne wczytywanie tych zasobów gwarantuje, że zostaną pobrane, zanim pliki CSS zostaną pobrane.

Wstępne wczytywanie plików CSS

Jeśli używasz krytycznego podejścia do CSS, musisz podzielić kod CSS na 2 części. Kluczowy kod CSS wymagany do renderowania części strony widocznej na ekranie jest wbudowany w <head> dokumentu, a niekrytyczny kod CSS jest zwykle leniwy – zawiera kod JavaScript. Oczekiwanie na wykonanie JavaScriptu przed wczytaniem niekrytego kodu CSS może powodować opóźnienia w renderowaniu podczas przewijania strony, dlatego warto wcześniej użyć elementu <link rel="preload">.

Wstępne wczytywanie plików JavaScript

Przeglądarki nie wykonują wstępnie wczytywanych plików, dlatego wstępne wczytywanie jest przydatne, ponieważ pozwala oddzielić pobieranie od wykonywania i poprawić wskaźniki takie jak czas do pełnej interaktywności. Wstępne wczytywanie działa najlepiej, gdy podzielisz pakiety JavaScript i wczytasz tylko najważniejsze fragmenty.

Jak stosować atrybut rel=preload

Najprostszym sposobem implementacji preload jest dodanie tagu <link> do <head> dokumentu:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

Podanie atrybutu as pomaga przeglądarce ustawić priorytet pobranego wstępnie zasobu zgodnie z jego typem, ustawić odpowiednie nagłówki i określić, czy zasób istnieje już w pamięci podręcznej. Akceptowane wartości tego atrybutu to: script, style, font, image i inne.

Niektóre typy zasobów, takie jak czcionki, są ładowane w trybie anonimowym. W ich przypadku ustaw atrybut crossorigin za pomocą parametru preload:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

Elementy <link> akceptują też atrybut type, który zawiera typ MIME połączonego zasobu. Przeglądarki używają wartości atrybutu type, aby mieć pewność, że zasoby są wstępnie wczytywane tylko wtedy, gdy ich typ pliku jest obsługiwany. Jeśli przeglądarka nie obsługuje określonego typu zasobu, zignoruje <link rel="preload">.

Możesz też wstępnie wczytywać zasoby dowolnego typu za pomocą nagłówka HTTP Link:

Link: </css/style.css>; rel="preload"; as="style"

Zaletą właściwości preload w nagłówku HTTP jest to, że przeglądarka nie musi analizować dokumentu w celu jego wykrycia, co w niektórych przypadkach może przynieść niewielkie ulepszenia.

Wstępne wczytywanie modułów JavaScript za pomocą pakietu Webpack

Jeśli korzystasz z pakietu modułów, który tworzy pliki kompilacji aplikacji, sprawdź, czy obsługuje on wstrzykiwanie tagów wstępnego wczytywania. W przypadku pakietu webpack w wersji 4.6.0 lub nowszej wstępne wczytywanie jest obsługiwane przez funkcję magicznych komentarzy w usłudze import():

import(_/* webpackPreload: true */_ "CriticalChunk")

Jeśli używasz starszej wersji pakietu Webpack, użyj wtyczki innej firmy, np. preload-webpack-plugin.

Wpływ wstępnego wczytywania na podstawowe wskaźniki internetowe

Wstępne wczytywanie to zaawansowana optymalizacja wydajności, która wpływa na szybkość wczytywania. Takie optymalizacje mogą prowadzić do zmian podstawowych wskaźników internetowych witryny, więc należy o nich pamiętać.

Największe wyrenderowanie treści (LCP)

Wstępne wczytywanie ma duży wpływ na największe wyrenderowanie treści (LCP) w przypadku czcionek i obrazów, ponieważ zarówno obrazy, jak i węzły tekstowe mogą być kandydatami LCP. Banery powitalne i duże partie tekstu renderowane za pomocą czcionek internetowych mogą przynieść dużą korzyść dzięki dobrze umieszczonej wskazówce dotyczącej wstępnego wczytywania. Należy ich używać, gdy istnieje możliwość szybszego dostarczenia użytkownikowi ważnych informacji.

Pamiętaj jednak, aby zachować ostrożność, jeśli chodzi o wstępne wczytywanie oraz inne optymalizacje. Szczególnie unikaj wstępnego wczytywania zbyt wielu zasobów. Jeśli priorytetowo nadano zbyt wiele zasobów, w rzeczywistości żaden z nich nie ma znaczenia. Skutki nadmiernego wczytywania wstępnego są szczególnie szkodliwe w przypadku wolniejszych sieci, gdzie różnica w przepustowości jest wyraźnie widoczna.

Zamiast tego skoncentruj się na kilku wartościowych zasobach, o których wiesz, że odpowiednie wstępne załadowanie strony będzie korzystne. Podczas wstępnego ładowania czcionek upewnij się, że stosujesz czcionki w formacie WOFF 2.0. Pozwoli to maksymalnie skrócić czas wczytywania zasobów. Ponieważ standard WOFF 2.0 obsługuje przeglądarki znakomicie, użycie starszych formatów, takich jak WOFF 1.0 lub TrueType (TTF), spowoduje opóźnienie LCP, jeśli kandydatem LCP jest węzeł tekstowy.

W przypadku LCP i JavaScriptu musisz upewnić się, że wysyłasz pełne znaczniki z serwera, aby skaner wstępnego wczytywania w przeglądarce działał prawidłowo. Jeśli udostępniasz środowisko, które do renderowania znaczników w całości opiera się na języku JavaScript i nie może wysyłać kodu HTML renderowanego przez serwer, warto zadbać o to, by skaner wstępnego wczytywania przeglądarki nie mógł wstępnie wczytać zasobów, które w przeciwnym razie byłyby dostępne dopiero po zakończeniu ładowania i wykonywania kodu JavaScript.

Skumulowane przesunięcie układu (CLS)

Skumulowane przesunięcie układu (CLS) jest szczególnie ważnym wskaźnikiem, jeśli chodzi o czcionki internetowe. Wartość CLS w znacznym stopniu współdziała z czcionkami internetowymi, które korzystają z właściwości CSS font-display do zarządzania ładowaniem czcionek. Aby zminimalizować przesunięcia układu związane z czcionkami internetowymi, rozważ te strategie:

  1. Wczytuj wstępnie czcionki z użyciem domyślnej wartości block dla font-display. To delikatna równowaga. Zablokowanie wyświetlania czcionek bez użycia kreacji zastępczej może być uznane za problem związany z wrażeniami użytkownika. Z jednej strony wczytywanie czcionek za pomocą font-display: block; eliminuje przesunięcia układu związane z czcionkami internetowymi. Z drugiej strony warto zadbać o jak najszybsze wczytanie czcionek internetowych, jeśli są one ważne dla wygody użytkowników. Połączenie wstępnego wczytywania z elementem font-display: block; może być akceptowanym kompromisem.
  2. Wczytuj wstępnie czcionki z użyciem wartości fallback dla font-display. fallback to kompromis między swap a block, ponieważ ma bardzo krótki okres blokowania.
  3. Użyj wartości optional dla elementu font-display bez wstępnego wczytywania. Jeśli czcionka internetowa nie ma kluczowego znaczenia dla wrażeń użytkownika, ale nadal jest używana do renderowania znacznej ilości tekstu na stronie, rozważ użycie wartości optional. W niekorzystnych warunkach optional będzie wyświetlać tekst na stronie przy użyciu czcionki zastępczej, a czcionka wczytuje się w tle, aby użyć jej podczas następnej nawigacji. W rezultacie w tych warunkach następuje poprawa CLS, ponieważ czcionki systemowe są renderowane natychmiast, a przy kolejnych wczytywaniu strony od razu jest ona wczytywana bez przesunięcia układu.

W przypadku czcionek internetowych CLS jest trudnym wskaźnikiem do optymalizacji. Jak zawsze, eksperymentuj w laboratorium, ale w zaufaniu do danych z pola ustal, czy Twoje strategie ładowania czcionek poprawiają CLS, czy go pogarszają.

od interakcji do kolejnego wyrenderowania (INP)

Interakcja do następnego wyrenderowania to dane, które określają reagowanie na dane wejściowe użytkownika. Ponieważ większość interakcji w internecie pochodzi z JavaScriptu, wstępne wczytywanie kodu JavaScript, który obsługuje ważne interakcje, może pomóc w utrzymaniu niższego INP strony. Pamiętaj jednak, że wstępne wczytywanie zbyt dużej ilości kodu JavaScript podczas uruchamiania może mieć niezamierzone negatywne konsekwencje, gdy zbyt wiele zasobów będzie rywalizować o przepustowość.

Musisz też uważać na sposób podziału kodu. Podział kodu to doskonała optymalizacja pozwalająca ograniczyć ilość kodu JavaScript ładowanego podczas uruchamiania. Jeśli jednak interakcje wykorzystują JavaScript wczytywany na samym początku, mogą być opóźnione. Aby to zrekompensować, trzeba zbadać intencję użytkownika i wprowadzić wstępne wczytanie niezbędnych fragmentów JavaScriptu, zanim nastąpi interakcja. Jednym z przykładów może być wstępne wczytywanie kodu JavaScript wymaganego do weryfikacji zawartości formularza, gdy którekolwiek z pól formularza jest zaznaczone.

Podsumowanie

Aby przyspieszyć działanie stron, wstępnie wczytuj ważne zasoby, które są wykrywane z opóźnieniem przez przeglądarkę. Wstępne wczytywanie wszystkich elementów przynosiłoby skutek odwrotny do zamierzonego, więc używaj polecenia preload z umiarem i mierz jego wpływ w świecie rzeczywistym.