Optymalizuj opóźnienie przy pierwszym działaniu

Sposoby szybszego reagowania na interakcje użytkowników.

Po kliknięciu nic się nie stało! Dlaczego nie mogę korzystać z tej strony? 😢

Pierwsze wyrenderowanie treści (FCP) i największy obraz treści (LCP) to wskaźniki, które mierzą czas potrzebny na wizualne wyrenderowanie (wyrenderowanie) treści na stronie. Czasy renderowania są ważne, jednak nie określają elastyczności wczytywania, czyli tego, jak szybko strona reaguje na interakcję użytkownika.

Opóźnienie przy pierwszym działaniu (FID) to podstawowe wskaźniki internetowe, które pokazują pierwsze wrażenia użytkownika związane z interaktywnością i responsywnością strony. Mierzy czas od pierwszej interakcji użytkownika ze stroną do chwili, w której przeglądarka jest w stanie na nią zareagować. FID to wskaźnik polowy i nie można go symulować w środowisku modułu. Do pomiaru opóźnienia reakcji wymagana jest rzeczywista interakcja użytkownika.

Dobre wartości to 2,5 sekundy, niskie – powyżej 4,0 sekundy, a wszystkie pozostałe wymagają poprawy.

Aby ułatwić prognozowanie FID w laboratorium, zalecamy stosowanie całkowitego czasu blokowania (TBT). Mierzą one różne rzeczy, ale poprawa wartości TBT zwykle odpowiada poprawkom FID.

Główną przyczyną słabego FID jest obciążone wykonywanie kodu JavaScript. Optymalizacja sposobu analizowania, kompilowania i wykonywania kodu JavaScript na stronie internetowej bezpośrednio ogranicza FID.

Intensywne wykonywanie JavaScriptu

Przeglądarka nie może odpowiedzieć na większość danych wejściowych użytkownika podczas wykonywania JavaScriptu w wątku głównym. Inaczej mówiąc, przeglądarka nie może odpowiadać na interakcje użytkownika, gdy wątek główny jest zajęty. Aby to poprawić:

Rozdzielanie długich zadań

Jeśli próbujesz zmniejszyć ilość kodu JavaScript, który wczytuje się na jednej stronie, warto podzielić długo działający kod na mniejsze, asynchroniczne zadania.

Długie zadania to okresy wykonywania JavaScriptu, w których użytkownicy mogą zauważyć, że interfejs użytkownika nie odpowiada. Każdy fragment kodu, który blokuje wątek główny przez co najmniej 50 ms, może zostać sklasyfikowany jako długie zadanie. Długie zadania to oznaka potencjalnego zmienności JavaScriptu (wczytywanie i wykonywanie więcej zadań niż użytkownik może teraz potrzebować). Dzielenie długich zadań może zmniejszyć opóźnienia wprowadzania danych w witrynie.

Długie zadania w Narzędziach deweloperskich w Chrome
Narzędzia deweloperskie w Chrome wizualizują długie zadania w panelu wydajności

FID powinien wyraźnie się poprawiać w miarę wdrożenia sprawdzonych metod, takich jak dzielenie kodu i dzielenie długich zadań. Choć TBT nie jest wskaźnikiem funkcjonalnym, przydaje się on do sprawdzania postępów w ostatecznej poprawie czasu do interakcji (TTI) i FID.

Zoptymalizuj stronę pod kątem gotowości do interakcji

W przypadku aplikacji internetowych, które w dużym stopniu korzystają z JavaScriptu, niskie wyniki FID i TBT mają kilka typowych przyczyn:

Wykonanie własnego skryptu może opóźnić gotowość do interakcji

  • Zbyt duży rozmiar kodu JavaScript, długi czas wykonywania i nieefektywne dzielenie treści na fragmenty mogą spowalniać reagowanie stron na dane wejściowe użytkownika oraz wpływać na FID, TBT i TI. Stopniowe ładowanie kodu i funkcji może pomóc rozłożyć ten trening i zwiększyć gotowość do interakcji.
  • W przypadku aplikacji renderowanych po stronie serwera piksele są szybko malowane na ekranie, ale uważaj, że interakcje użytkownika są blokowane przez duże uruchomienia skryptów (np. przez nawodnienie w celu podłączenia detektorów zdarzeń). Może to potrwać kilkaset milisekund, a czasem nawet sekund, jeśli dzielisz kod na podstawie trasy. Rozważ przeniesienie większej ilości logiki po stronie serwera lub generowanie większej ilości treści statycznie podczas kompilacji.

Poniżej znajdziesz wyniki TBT przed zoptymalizowaniem wczytywania własnego skryptu dla aplikacji i po nim. Dzięki odsunięciu kosztownego wczytywania (i wykonania) skryptu z niezbędnego elementu z dala od krytycznej ścieżki użytkownicy mogli znacznie szybciej wejść w interakcję ze stroną.

Poprawa wyniku TBT w Lighthouse po zoptymalizowaniu własnego skryptu.

Pobieranie danych może wpływać na wiele aspektów gotowości do interakcji

  • Oczekiwanie na kaskadową kaskadę pobierania (np. JavaScript i pobieranie danych dla komponentów) może wpływać na czas oczekiwania na interakcję. Postaraj się zminimalizować zależność od kaskadowego pobierania danych.
  • Duże, wbudowane magazyny danych mogą wydłużyć czas analizy HTML i wpłynąć zarówno na wskaźniki wyrenderowania, jak i interakcji. Postaraj się maksymalnie ograniczyć ilość danych, które muszą być przetworzone po stronie klienta.

Wykonanie skryptu innej firmy może również opóźnić opóźnienie interakcji

  • Wiele witryn zawiera tagi i narzędzia analityczne innych firm, które mogą zapewnić ciągłość działania sieci i sprawić, że wątek główny okresowo przestanie odpowiadać, co wpłynie na opóźnienie interakcji. Badaj wczytywanie kodu zewnętrznego na żądanie (np. nie wczytuj reklam w części strony widocznej po przewinięciu, dopóki nie zbliżą się do widocznego obszaru).
  • W niektórych przypadkach skrypty innych firm mogą wyprzedzać te własne pod względem priorytetu i przepustowości w wątku głównym, a także opóźniać moment, w którym strona jest gotowa do interakcji. Staraj się najpierw wczytywać to, co według Ciebie ma największą wartość dla użytkowników.

Użyj skryptu internetowego

Zablokowanie wątku głównego jest jedną z głównych przyczyn opóźnienia wprowadzania. Roboty internetowe umożliwiają uruchamianie JavaScriptu w wątku w tle. Przeniesienie operacji niebędących interfejsem użytkownika do osobnego wątku roboczego może skrócić czas blokowania wątków głównych i w konsekwencji poprawić FID.

Aby ułatwić sobie korzystanie z pracowników internetowych w swojej witrynie, możesz skorzystać z tych bibliotek:

  • Comlink: biblioteka pomocnicza, która wyodrębnia streszczenie postMessage i ułatwia korzystanie z niej.
  • Workway: uniwersalne narzędzie do eksportowania plików Web Workway.
  • Workerize: przenieś moduł do instancji roboczej.

Skrócenie czasu wykonywania JavaScriptu

Ograniczenie ilości kodu JavaScript na stronie pozwala skrócić czas potrzebny przeglądarce na wykonanie kodu JavaScript. To przyspiesza reagowanie przeglądarki na interakcje użytkownika.

Aby zmniejszyć ilość kodu JavaScript wykonywanego na stronie:

  • Odłóż nieużywany JavaScript
  • Minimalizowanie nieużywanych elementów polyfill

Odłóż nieużywany JavaScript

Domyślnie cały kod JavaScript blokuje renderowanie. Gdy przeglądarka napotka tag skryptu, który prowadzi do zewnętrznego pliku JavaScript, musi wstrzymać działanie oraz pobrać, przeanalizować, skompilować i wykonać ten kod JavaScript. Należy więc wczytywać tylko kod, który jest potrzebny do działania strony lub odpowiada na dane wejściowe użytkownika.

Na karcie Zasięg w Narzędziach deweloperskich w Chrome możesz sprawdzić, w jakim stopniu kod JavaScript nie jest używany na Twojej stronie internetowej.

Karta Zasięg.

Aby ograniczyć nieużywany JavaScript:

  • Podziel pakiet na kilka części.
  • Odłóż wszystkie niekrytyczne skrypty JavaScript, w tym skrypty innych firm, za pomocą async lub defer.

Podział kodu polega na podzieleniu pojedynczego dużego pakietu JavaScript na mniejsze fragmenty, które mogą być ładowane warunkowo (tzw. leniwe ładowanie). Większość nowszych przeglądarek obsługuje składnię dynamicznego importowania, co umożliwia pobieranie modułów na żądanie:

import('module.js').then((module) => {
  // Do something with the module.
});

Dynamiczne importowanie kodu JavaScript podczas określonych interakcji użytkownika (np. zmiana trasy lub wyświetlenie okna modalnego) sprawi, że kod, który nie jest używany przy wstępnym wczytaniu strony, będzie pobierany tylko w razie potrzeby.

Poza ogólną obsługą przeglądarek w wielu różnych systemach kompilacji można używać składni importu dynamicznego.

  • Jeśli używasz pakietu webpack, Podsumowania lub Parcel jako narzędzia do tworzenia pakietów modułów, skorzystaj z ich obsługi dynamicznego importowania.
  • Platformy po stronie klienta, takie jak React, Angular i Vue, zapewniają abstrakcje ułatwiające leniwe ładowanie na poziomie komponentu.

Oprócz podziału kodu zawsze używaj funkcji asynchronicznej lub opóźnienia w przypadku skryptów, które nie są niezbędne w przypadku treści w części strony krytycznej ani w części strony widocznej na ekranie.

<script defer src="…"></script>
<script async src="…"></script>

O ile nie ma konkretnego powodu, aby tego nie robić, wszystkie skrypty innych firm powinny być domyślnie wczytywane z elementami defer lub async.

Minimalizowanie nieużywanych elementów polyfill

Jeśli tworzysz kod z wykorzystaniem nowoczesnej składni JavaScript i odwołujesz się do interfejsów API nowoczesnych przeglądarek, musisz go przetranspilować i dodać kod polyfill, aby działał w starszych przeglądarkach.

Jednym z najważniejszych problemów z wydajnością w przypadku umieszczenia kodu polyfill i transpilacji w witrynie jest to, że nowsze przeglądarki nie powinny go pobierać, jeśli go nie potrzebują. Aby ograniczyć rozmiar kodu JavaScript w swojej aplikacji, jak najbardziej zminimalizuj nieużywane elementy polyfill i ogranicz ich użycie do środowisk, w których są potrzebne.

Aby zoptymalizować wykorzystanie kodu polyfill w witrynie:

  • Jeśli używasz transpilera Babel, użyj @babel/preset-env, aby uwzględnić tylko kody polyfill potrzebne w przeglądarkach, na które chcesz kierować reklamy. W przypadku Babel 7.9 włącz opcję bugfixes, aby jeszcze bardziej ograniczyć zbędne elementy polyfill.
  • Użyj wzorca moduł/nomodule, aby przesłać 2 osobne pakiety (@babel/preset-env obsługuje też to za pomocą target.esmodules)

    <script type="module" src="modern.js"></script>
    <script nomodule src="legacy.js" defer></script>
    

    Wiele nowszych funkcji ECMAScript skompilowanych z Babel jest już obsługiwanych w środowiskach obsługujących moduły JavaScript. W ten sposób upraszczasz proces – masz pewność, że tylko transpilowany kod jest używany w przeglądarkach, które go faktycznie potrzebują.

Narzędzia dla programistów

Dostępnych jest wiele narzędzi do pomiaru i debugowania FID:

Dziękujemy Philipowi Walton, Kayce Basques, Ilya Grigorik i Annie Sullivan za ich recenzje.