Skrypty innych firm wpływają na wydajność, dlatego ważne jest, aby regularnie je sprawdzać i stosować skuteczne techniki ich wczytywania. Z tego Codelab dowiesz się, jak zoptymalizować wczytywanie zasobów innych firm. Obejmuje ona te techniki:
Opóźnianie wczytywania skryptu
Leniwe ładowanie zasobów niekrytycznych
Wstępne łączenie się z wymaganymi źródłami
Załączona przykładowa aplikacja zawiera prostą stronę internetową z 3 funkcjami pochodzącymi ze źródeł zewnętrznych:
Wstawiony film
Biblioteka wizualizacji danych do renderowania wykresu liniowego
Widget udostępniania w mediach społecznościowych
Najpierw zmierz skuteczność aplikacji, a potem zastosuj poszczególne techniki, aby poprawić różne aspekty jej działania.
Pomiar wyników
Najpierw otwórz przykładową aplikację w widoku pełnoekranowym:
- Kliknij Remixuj do edycji, aby umożliwić edycję projektu.
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran .
Przeprowadź audyt wydajności Lighthouse na stronie, aby ustalić wydajność bazową:
- Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
- Kliknij kartę Lighthouse.
- Kliknij Mobilne.
- Zaznacz pole wyboru Wydajność. (możesz odznaczyć pozostałe pola w sekcji Audyt).
- Kliknij Symulowana szybka sieć 3G, 4-krotne spowolnienie CPU.
- Zaznacz pole wyboru Wyczyść pamięć podręczną.
- Kliknij Uruchom audyty.
Gdy przeprowadzisz audyt na swoim komputerze, dokładne wyniki mogą się różnić, ale powinieneś zauważyć, że czas pierwszego wyrenderowania treści (FCP) jest dość długi, a Lighthouse sugeruje 2 możliwości, które warto sprawdzić: usuń zasoby blokujące renderowanie i nawiązanie wstępnego połączenia z wymaganymi źródłami. (nawet jeśli wszystkie dane są zielone, optymalizacje nadal przynoszą poprawę).
Opóźnianie kodu JavaScript firm zewnętrznych
Podczas kontroli Eliminowanie zasobów blokujących renderowanie stwierdziliśmy, że możesz zaoszczędzić trochę czasu, opóźniając skrypt pochodzący z d3js.org:
D3.js to biblioteka JavaScript do tworzenia wizualizacji danych. Plik script.js
w próbnej aplikacji używa funkcji pomocniczych D3 do tworzenia wykresu liniowego SVG i dodawania go do strony. Ważna jest kolejność operacji: funkcja script.js
musi zostać wykonana po przeanalizowaniu dokumentu i wczytaniu biblioteki D3, dlatego jest uwzględniona tuż przed zamykającym tagiem </body>
w funkcji index.html
.
Skrypt D3 jest jednak uwzględniony w sekcji <head>
strony, co blokuje analizę reszty dokumentu:
Dodanie do tagu skryptu 2 magicznych atrybutów może odblokować parsowanie:
async
zapewnia, że skrypty są pobierane w tle i wykonywane przy pierwszej okazji po zakończeniu pobierania.defer
sprawia, że skrypty są pobierane w tle i uruchamiane po zakończeniu parsowania.
Ten wykres nie jest tak naprawdę kluczowy dla całej strony i najprawdopodobniej będzie widoczny poniżej załamu, więc użyj defer
, aby sprawdzić, czy nie ma blokowania przez parsowanie.
Krok 1. Załaduj skrypt asynchronicznie za pomocą atrybutu defer
W wierszu 17 w pliku index.html
dodaj atrybut defer
do elementu <script>
:
<script src="https://d3js.org/d3.v3.min.js" defer></script>
Krok 2. Sprawdź, czy operacje są wykonywane we właściwej kolejności
Ponieważ D3 jest opóźnione, funkcja script.js
zostanie wykonana, zanim D3 będzie gotowe, co spowoduje błąd.
Skrypty z atrybutem defer
są wykonywane w kolejności, w jakiej zostały określone. Aby mieć pewność, że element script.js
zostanie wykonany po zakończeniu etapu D3, dodaj do niego element defer
i przesuń go do <head>
dokumentu, tuż po elemencie <script>
etapu D3. Teraz nie blokuje już parsowania i pobieranie rozpoczyna się wcześniej.
<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>
Leniwe ładowanie zasobów z innych witryn
Wszystkie zasoby, które znajdują się w części strony widocznej po przewinięciu, nadają się do leniwego ładowania.
Przykładowa aplikacja zawiera film z YouTube umieszczony w tagu iframe. Aby sprawdzić, ile żądań wysyła strona i które z nich pochodzą z osadzonego elementu iframe YouTube:
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran .
- Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
- Kliknij kartę Sieć.
- Zaznacz pole wyboru Disable cache (Wyłącz pamięć podręczną).
- W menu Ograniczanie wybierz Szybki 3G.
- Odśwież stronę.
Z panelu Sieć wynika, że strona wysłała łącznie 28 żądań i przesłała prawie 1 MB zasobów skompresowanych.
Aby zidentyfikować żądania wysłane przez YouTube iframe
, poszukaj identyfikatora filmu 6lfaiXM6waw
w kolumnie Initiator (Inicjator). Aby pogrupować wszystkie prośby według domeny:
W panelu Sieć kliknij prawym przyciskiem myszy tytuł kolumny.
W menu wybierz kolumnę Domeny.
Aby posortować żądania według domeny, kliknij tytuł kolumny Domeny.
Nowe sortowanie ujawnia, że do domen Google wysyłane są dodatkowe żądania. W ogóle element iframe YouTube wysyła 14 żądań skryptów, arkuszy stylów, obrazów i czcionek. Jeśli jednak użytkownicy nie przewiną strony w dół, aby odtworzyć film, nie będą potrzebować wszystkich tych zasobów.
Odczekanie z leniwym wczytaniem filmu do momentu, gdy użytkownik przewinie stronę w dół, zmniejsza liczbę żądań wysyłanych przez stronę na początku. Dzięki temu podejściu oszczędzasz dane użytkowników i przyspieszasz wczytywanie.
Jednym ze sposobów implementacji wolnego wczytywania jest użycie Intersection Observer, czyli interfejsu API przeglądarki, który powiadamia, gdy element wchodzi do widocznego obszaru lub z niego wychodzi.
Krok 1. Zapobieganie wczytywaniu filmu na początku
Aby wczytywać iframe filmu z opóźnieniem, musisz najpierw uniemożliwić jego wczytywanie w zwykły sposób. Aby to zrobić, zastąp atrybut src
atrybutem data-src
, aby podać adres URL filmu:
<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
data-src
to atrybut danych, który umożliwia przechowywanie dodatkowych informacji w standardowych elementach HTML. Atrybut danych może mieć dowolną nazwę, o ile zaczyna się od „data-”.
Element iframe bez atrybutu src
się nie wczyta.
Krok 2. Użyj Intersection Observer do leniwego wczytywania filmu
Aby wczytać film, gdy użytkownik przewinie do niego, musisz wiedzieć, kiedy to nastąpi. Właśnie w tym miejscu przydaje się interfejs Intersection Observer API. Interfejs Intersection Observer API umożliwia zarejestrowanie funkcji wywołania zwrotnego, która jest wykonywana, gdy element, który chcesz śledzić, wchodzi do widoku lub z niego wychodzi.
Aby rozpocząć, utwórz nowy plik o nazwie lazy-load.js
:
- Kliknij Nowy plik i nadaj mu nazwę.
- Kliknij Dodaj ten plik.
Dodaj tag skryptu do nagłówka dokumentu:
<script src="/lazy-load.js" defer></script>
W pliku lazy-load.js
utwórz nową funkcję IntersectionObserver
i przekaż jej funkcję wywołania zwrotnego do wykonania:
// create a new Intersection Observer
let observer = new IntersectionObserver(callback);
Teraz podaj observer
element docelowy do obejrzenia (w tym przypadku iframe filmu), przekazując go jako argument w metodzie observe
:
// the element that you want to watch
const element = document.querySelector('iframe');
// register the element with the observe method
observer.observe(element);
callback
otrzymuje listę obiektów IntersectionObserverEntry
i sam obiekt IntersectionObserver
. Każdy wpis zawiera element target
oraz właściwości opisujące jego wymiary, położenie, czas wejścia do widoku i inne informacje. Jedną z właściwości IntersectionObserverEntry
jest isIntersecting
– wartość logiczna, która jest równa true
, gdy element wchodzi do widocznego obszaru.
W tym przykładzie target
to iframe
. isIntersecting
jest równe true
, gdy target
znajdzie się w widocznym obszarze. Aby zobaczyć to w akcji, zastąp callback
tą funkcją:
let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
console.log(entry.target);
console.log(entry.isIntersecting);
});
});
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran .
- Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
- Kliknij kartę Konsola.
Spróbuj przewinąć w górę i w dół. Wartość isIntersecting
powinna się zmienić, a element docelowy powinien zostać zarejestrowany w konsoli.
Aby załadować film, gdy użytkownik przewinie do jego pozycji, użyj wyrażenia isIntersecting
jako warunku do uruchomienia funkcji loadElement
, która pobiera wartość z elementu iframe
data-src
i ustawia ją jako atrybut src
elementu iframe
. Ta wymiana powoduje wczytanie filmu. Następnie, gdy film zostanie załadowany, wywołaj metodę unobserve
elementu observer
, aby zatrzymać odtwarzanie elementu docelowego:
let observer = new IntersectionObserver(function (entries, observer) {
entries.forEach(entry => {
console.log(entry.target);
console.log(entry.isIntersecting);
});
});
if (entry.isIntersecting) {
// do this when the element enters the viewport
loadElement(entry.target);
// stop watching
observer.unobserve(entry.target);
}
});
});
function loadElement(element) {
const src = element.getAttribute('data-src');
element.src = src;
}
Krok 3. Ponownie oceń skuteczność
Aby sprawdzić, jak zmienił się rozmiar i liczba zasobów, otwórz panel Sieć w Narzędziach deweloperskich i ponownie załaduj stronę. Z panelu Sieć wynika, że strona wysłała 14 żądań i wygenerowała tylko 260 KB. To znaczna poprawa.
Przewiń stronę w dół i obserwuj panel Sieć. Gdy przejdziesz do filmu, zobaczysz, że strona powoduje wysyłanie dodatkowych żądań.
Wstępne łączenie się z wymaganymi źródłami
Opóźniłeś/opóźniłaś wczytywanie niekrytycznych skryptów JavaScript i wykorzystałeś/wykorzystałaś opóźnione wczytywanie żądań do YouTube, więc teraz nadszedł czas na optymalizację pozostałych treści innych firm.
Dodanie atrybutu rel=preconnect
do linku powoduje, że przeglądarka nawiązuje połączenie z domeną przed wysłaniem żądania dotyczącego tego zasobu. Ten atrybut najlepiej używać w przypadku źródeł, które udostępniają zasoby, których strona na pewno potrzebuje.
W ramach pierwszego kroku przeprowadzony przez Ciebie audyt Lighthouse sugeruje, że w celu wstępnego połączenia się z wymaganymi źródłami możesz zaoszczędzić około 400 ms, nawiązując wczesne połączenia z witrynami staticxx.facebook.com i youtube.com:
Ponieważ film w YouTube jest teraz ładowany z opóźnieniem, pozostaje tylko staticxx.facebook.com, czyli źródło widżetu udostępniania w mediach społecznościowych. Utworzenie wstępnego połączenia z tą domeną jest tak proste, jak dodanie tagu <link>
do <head>
w dokumencie:
<link rel="preconnect" href="https://staticxx.facebook.com">
Ponowna ocena skuteczności
Oto stan strony po optymalizacji. Aby przeprowadzić kolejny audyt Lighthouse, wykonaj czynności podane w sekcji Pomiar wydajności w codelab.