Skrypty innych firm wpływają na wydajność, dlatego tak ważne jest regularne ich sprawdzanie i stosowanie efektywnych metod ich wczytywania. Z tego Codelab dowiesz się, jak zoptymalizować wczytywanie zasobów innych firm. Obejmuje ona te techniki:
Opóźnianie wczytywania skryptu
Leniwe ładowanie niekrytycznych zasobów
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 każdą technikę, aby poprawić różne aspekty jej skuteczności.
Pomiar wyników
Najpierw otwórz przykładową aplikację w widoku pełnoekranowym:
- Kliknij Remix to Edit (Zmiksuj do edycji), aby umożliwić edycję projektu.
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran.
Aby ustalić wydajność bazową, przeprowadź audyt wydajności w Lighthouse na stronie:
- Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
- Kliknij kartę Lighthouse.
- Kliknij Urządzenia 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 Przeprowadź audyty.
Gdy przeprowadzisz audyt na swoim urządzeniu, 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 rozwiązania tego problemu: usunięcie zasobów blokujących renderowanie i uprzednie połączenie z wymaganymi źródłami. (nawet jeśli wszystkie dane są zielone, optymalizacje nadal przynoszą poprawę).
Odrocz kod JavaScript innej firmy
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 przykładowej aplikacji używa funkcji narzędziowych D3 do utworzenia wykresu liniowego SVG i dołączenia 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 elementach index.html
dodaj atrybut defer
do elementu <script>
:
<script src="https://d3js.org/d3.v3.min.js" defer></script>
Krok 2. Upewnij się, że operacje są wykonywane w prawidłowej 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ż za elementem <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ę poniżej pola widzenia, nadają się do leniwego ładowania.
Przykładowa aplikacja ma film z YouTube umieszczony w elemencie 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 Wyłącz pamięć podręczną.
- W menu Throttling wybierz Szybka sieć 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 zgrupować wszystkie żądania 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 załaduje.
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ć, jak to działa, 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ół. Powinna pojawić się wartość zmiany isIntersecting
oraz element docelowy zarejestrowany w konsoli.
Aby wczytać film, gdy użytkownik przewinie stronę do jego pozycji, użyj parametru isIntersecting
, aby uruchomić funkcję loadElement
, która pobiera wartość z wartości data-src
elementu iframe
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 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.
Audyt Lighthouse przeprowadziliśmy w pierwszym kroku sugerowanego w sekcji Wstępne łączenie z wymaganymi źródłami. Możesz zaoszczędzić około 400 ms, nawiązując wcześniejsze połączenia ze 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 dokumentie:
<link rel="preconnect" href="https://staticxx.facebook.com">
Ponowna ocena skuteczności
Oto stan strony po optymalizacji. Wykonaj czynności opisane w sekcji Pomiar wydajności ćwiczenia z programowania, aby przeprowadzić kolejny audyt Lighthouse.