Optymalizowanie ładowania skryptów zewnętrznych w Next.js

Poznaj wizję komponentu skryptu Next.js, który udostępnia wbudowane rozwiązanie do optymalizacji wczytywania skryptów innych firm.

Leena Sohoni
Leena Sohoni

Około 45% żądań z witryn wyświetlanych na urządzeniach mobilnych i komputerach to żądania innych firm, z których 33% to skrypty. Rozmiar, czas oczekiwania i wczytywanie skryptów innych firm może w znacznym stopniu wpływać na wydajność witryny. Komponent skryptu Next.js zawiera wbudowane sprawdzone metody i ustawienia domyślne, które pomagają programistom wprowadzać do aplikacji skrypty innych firm i od razu rozwiązywać potencjalne problemy z wydajnością.

Skrypty firm zewnętrznych i ich wpływ na skuteczność reklam.

Skrypty innych firm pozwalają programistom stron internetowych na wykorzystanie istniejących rozwiązań do implementacji typowych funkcji i skrócenia czasu programowania. Jednak twórcy tych skryptów zwykle nie mają żadnego motywacji, aby zastanawiać się nad wpływem na wydajność strony. Skrypty te są też czarnymi skrzydłami dla programistów, którzy z nich korzystają.

Skrypty generują znaczną liczbę bajtów pobieranych przez witryny z różnych kategorii żądań zewnętrznych. Domyślnie przeglądarka nadaje priorytet skryptom na podstawie ich umiejscowienia w dokumencie, co może opóźniać wykrywanie lub wykonywanie skryptów kluczowych dla wygody użytkownika.

Biblioteki innych firm wymagane do układu strony powinny być wcześnie wczytywane, aby strona została wyrenderowana. Osoby trzecie, które nie są wymagane do wstępnego renderowania, powinny zostać odroczone, aby nie blokowały innych procesów w wątku głównym. W Lighthouse dostępne są 2 kontrole związane z oznaczaniem skryptów blokujących renderowanie lub blokowanie wątków głównych.

Audyty Lighthouse dotyczące: wyeliminuj zasoby blokujące renderowanie i minimalizuj wykorzystanie zasobów zewnętrznych

Warto zadbać o sekwencję wczytywania zasobów strony, tak aby zasoby o znaczeniu krytycznym nie były opóźnione ani nie blokowały zasobów o znaczeniu krytycznym.

Istnieją sprawdzone metody zmniejszania wpływu działań podejmowanych na działania firm zewnętrznych, ale nie wszyscy wiedzą, jak je wdrożyć w każdej firmie, z której korzystają. Może to być skomplikowane, ponieważ:

  • Witryny korzystają średnio z 21–23 różnych firm zewnętrznych (w tym skryptów) na urządzeniach mobilnych i komputerach. Wykorzystanie i zalecenia mogą się różnić w zależności od usługi.
  • Implementacja wielu rozwiązań zewnętrznych może się różnić w zależności od tego, czy używana jest konkretna platforma lub biblioteka interfejsu.
  • Często są wprowadzane nowsze biblioteki zewnętrzne.
  • Różne wymagania biznesowe związane z tą samą firmą zewnętrzną utrudniają deweloperom ustandaryzowanie jej stosowania.

Aurora skupia się na skryptach innych firm

W ramach współpracy firmy Aurora z platformami i narzędziami internetowymi typu open source firma zapewnia stosowanie silnych wartości domyślnych i sprawdzonych narzędzi, które pomagają programistom w ulepszaniu takich aspektów wygody użytkowników jak wydajność, dostępność, bezpieczeństwo czy gotowość na urządzenia mobilne. W 2021 roku skupiliśmy się na wspieraniu stosów platform w celu poprawy wrażeń użytkowników i danych podstawowych wskaźników internetowych.

Jednym z najważniejszych kroków do osiągnięcia naszego celu, którym jest zwiększenie wydajności platformy, było znalezienie w Next.js idealnej sekwencji wczytywania skryptów innych firm. Platformy takie jak Next.js mają wyjątkowe możliwości dostarczania przydatnych wartości domyślnych i funkcji, które pomagają programistom efektywnie ładować zasoby, w tym usługi innych firm. Przeanalizowaliśmy obszerne dane HTTP Archive i Lighthouse, aby ustalić, które firmy zewnętrzne najczęściej blokują renderowanie na różnych platformach.

Aby rozwiązać problem blokowania skryptów innych firm w wątku głównym, stworzyliśmy komponent skryptu. Komponent obejmuje funkcje sekwencjonowania, aby zapewnić programistom lepszą kontrolę nad wczytywaniem skryptów zewnętrznych.

Sekwencjonowanie skryptów innych firm bez komponentu platformy

Dostępne wskazówki, które pomagają ograniczyć wpływ skryptów blokujących renderowanie, zawierają te metody efektywnego wczytywania i sekwencjonowania skryptów zewnętrznych:

  1. Użyj atrybutu async lub defer z tagami <script>, które informują przeglądarkę o wczytywaniu niekrytycznych skryptów spoza witryny bez blokowania parsera dokumentów. Skrypty, które nie są wymagane do wstępnego wczytywania strony lub pierwszej interakcji użytkownika, można uznać za niekrytyczne.

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. Nawiązuj wcześniejsze połączenia z wymaganymi źródłami za pomocą funkcji preconnect i dns-prefetch. Dzięki temu najważniejsze skrypty mogą rozpocząć się wcześniej.

       <head>
           <link rel="preconnect" href="http://PreconnThis.com">
           <link rel="dns-prefetch" href="http://PrefetchThis.com">
       </head>
    
  3. Leniwe ładowanie zasobów zewnętrznych i umieszczanych na stronie po zakończeniu wczytywania treści strony głównej lub po przewinięciu przez użytkownika do części strony, w której znajdują się te elementy.

Komponent skryptu Next.js

Komponent Skrypt Next.js implementuje powyższe metody sekwencjonowania skryptów i udostępnia szablon, za pomocą którego programiści mogą określić strategię wczytywania. Po określeniu odpowiedniej strategii wczyta się ona optymalnie bez blokowania innych kluczowych zasobów.

Komponent Skrypt jest oparty na tagu HTML <script> i umożliwia ustawienie priorytetu wczytywania skryptów innych firm za pomocą atrybutu strategii.

// Example for beforeInteractive:
<Script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />

// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />

// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />

Atrybut strategii może mieć 3 wartości.

  1. beforeInteractive: ta opcja może być używana w przypadku kluczowych skryptów, które powinny zostać wykonane, zanim strona stanie się interaktywna. Dzięki Next.js takie skrypty są umieszczane w początkowym kodzie HTML na serwerze i wykonywane przed innym kodem JavaScriptu własnym. Do tej strategii należą zarządzanie zgodą użytkowników, skrypty wykrywania botów lub biblioteki pomocnicze wymagane do renderowania krytycznych treści.

  2. afterInteractive: to zastosowana strategia domyślna, która odpowiada wczytywaniu skryptu z atrybutem odroczenia. Należy go używać w przypadku skryptów, które przeglądarka może uruchamiać, gdy strona jest interaktywna, np. skryptów analitycznych. Next.js wstawia te skrypty po stronie klienta i uruchamia się je, gdy strona jest nawodowana. Z tego względu, o ile nie określono inaczej, wszystkie skrypty innych firm zdefiniowane za pomocą komponentu Script są odkładane przez Next.js, co powoduje silną wartość domyślną.

  3. lazyOnload: ta opcja umożliwia leniwe ładowanie skryptów o niskim priorytecie, gdy przeglądarka jest nieaktywna. Funkcje udostępniane przez te skrypty nie są wymagane natychmiast po tym, gdy strona stanie się interaktywna, np. w przypadku czatu lub wtyczek do mediów społecznościowych.

Deweloperzy mogą określić strategię, aby poinformować Next.js o tym, jak ich aplikacja używa skryptu. Dzięki temu platforma może stosować optymalizacje i sprawdzone metody do wczytywania skryptu, a jednocześnie zapewnić najlepszą sekwencję wczytywania.

Korzystając z komponentu Skrypt, programiści mogą umieścić w aplikacji skrypt zewnętrzny w dowolnym miejscu, aby umożliwić instalowanie późno w aplikacji, lub na poziomie dokumentu (w przypadku skryptów krytycznych). Oznacza to, że komponent skryptu może znajdować się razem z komponentem za pomocą skryptu. Po nawodnieniu skrypt jest wprowadzany w nagłówek początkowo renderowanego dokumentu lub w dolną część ciała, w zależności od zastosowanej strategii.

Pomiar wpływu

Na podstawie szablonów dla aplikacji handlowej Next.js i bloga dla początkujących stworzyliśmy 2 aplikacje demonstracyjne, które pomogły zmierzyć wpływ skryptów innych firm. Firmy zewnętrzne często używane do obsługi Menedżera tagów Google i umieszczania w mediach społecznościowych były najpierw widoczne na stronach tych aplikacji bezpośrednio, a potem w komponencie Skrypt. Następnie porównaliśmy skuteczność tych stron za pomocą narzędzia WebPageTest.

Skrypty innych firm w aplikacji handlowej Next.js

Do szablonu aplikacji handlowej na potrzeby wersji demonstracyjnej dodano skrypty firm zewnętrznych w sposób podany poniżej.

Przed Po
Menedżer tagów Google asynchroniczny Komponent skryptu ze strategią = afterInteractive w przypadku obu skryptów
Przycisk Obserwuj na Twitterze bez asynchronicznego i opóźnienia
Konfiguracja skryptu i komponentu na potrzeby wersji demonstracyjnej 1 z 2 skryptami.

Poniżej widać porównanie wizualnego postępu w przypadku obu wersji zestawu startowego dla sklepów Next.js. Jak widać, LCP pojawia się prawie 1 sekundę wcześniej, gdy komponent Skrypt jest włączony z właściwą strategią wczytywania.

Porównanie taśmy filmowej przedstawiające improwizację w skali LCP

Skrypty innych firm na blogu Next.js

Skrypty innych firm zostały dodane do demonstracyjnej aplikacji do blogowania w podany niżej sposób.

Przed Po
Menedżer tagów Google asynchroniczny Komponent skryptu ze strategią = leniwe ładowanie dla każdego z 4 skryptów
Przycisk Obserwuj na Twitterze z asynchronizacją
Przycisk subskrypcji w YouTube bez asynchronicznego i opóźnienia
Przycisk Obserwuj w LinkedIn bez asynchronicznego i opóźniania
Konfiguracja skryptów i komponentów skryptu na potrzeby wersji demonstracyjnej 2 z 4 skryptami.
Film przedstawiający postęp wczytywania strony indeksu z komponentem skryptu i bez niego. Zastosowanie komponentu Skrypt pozwala poprawić FCP o 0,5 sekundy.

Jak widać na filmie, pierwsze wyrenderowanie treści (FCP) zachodzi na stronie w 0,9 sekundy bez komponentu skryptu i w 0,4 sekundy z komponentem skryptu.

Co dalej z komponentem Skrypt

Opcje strategii w przypadku afterInteractive i lazyOnload dają dużą kontrolę nad skryptami blokującymi renderowanie, ale badamy też inne opcje, które zwiększyłyby przydatność komponentu Skrypt.

Korzystanie z procesów internetowych

Roboty internetowe mogą służyć do uruchamiania niezależnych skryptów w wątkach w tle. Może to zwolnić wątek główny do obsługi zadań związanych z przetwarzaniem interfejsu użytkownika i zwiększyć wydajność. Skrypty Web Worker najlepiej nadają się do odciążania przetwarzania JavaScriptu od obsługi w interfejsie użytkownika z wątku głównego. Skrypty używane do obsługi klienta lub marketingu, które zwykle nie komunikują się z interfejsem użytkownika, mogą się dobrze sprawdzić w wątku w tle. Niewielka biblioteka innej firmy – PartyTown – może posłużyć do odizolowania takich skryptów od instancji roboczej.

Przy obecnej implementacji komponentu skryptu Next.js zalecamy odroczenie tych skryptów w wątku głównym za pomocą strategii afterInteractive lub lazyOnload. W przyszłości proponujemy wprowadzenie nowej opcji strategii – 'worker', która umożliwi Next.js korzystanie z PartyTown lub rozwiązania niestandardowego do uruchamiania skryptów w zasobach internetowych. Chętnie poznamy komentarze deweloperów dotyczące tego dokumentu RFC.

Minimalizowanie CLS

Elementy umieszczone przez inne firmy, takie jak reklamy, filmy czy kanały w mediach społecznościowych, mogą powodować zmiany układu w przypadku leniwego ładowania. Ma to wpływ na wrażenia użytkowników i na dane skumulowane przesunięcie układu (CLS) w przypadku strony. Wartość CLS można zminimalizować, określając rozmiar kontenera, w którym zostanie wczytany umieszczony element.

Komponentu można używać do wczytywania elementów umieszczonych na stronie, które mogą powodować przesunięcia układu. Rozważamy rozszerzenie jej, aby udostępnić opcje konfiguracji, które pomogą zmniejszyć CLS. Możesz go udostępnić w samym komponencie skryptu lub jako komponent towarzyszący.

Komponenty opakowania

Składnia i strategia wczytywania w przypadku stosowania popularnych skryptów zewnętrznych, takich jak Google Analytics czy Menedżer tagów Google (GTM), są zwykle stałe. Można je dodatkowo ująć w pojedyncze komponenty kodów poszczególnych typów skryptu. Programiści będą mieli dostęp tylko do minimalnego zestawu atrybutów specyficznych dla aplikacji (np. identyfikatora śledzenia). Komponenty paczki pomogą programistom przez:

  1. Ułatwiają dodawanie popularnych tagów skryptu.
  2. Upewnienie się, że platforma wykorzystuje najbardziej optymalną strategię.

Podsumowanie

Skrypty innych firm są zwykle tworzone w taki sposób, aby uwzględniać określone funkcje w korzystającej z witryny. Aby ograniczyć wpływ niekrytycznych skryptów, zalecamy ich odroczenie – robi to domyślnie komponent skryptu Next.js. Deweloperzy mają pewność, że dołączone skrypty nie będą opóźniać istotnych funkcji, chyba że jednoznacznie zastosują strategię beforeInteractive. Podobnie jak w przypadku komponentu Skrypt Next.js, programiści platform mogą również opracować te funkcje w innych platformach. Pracujemy nad wdrożeniem podobnego komponentu z zespołem Nuxt.js. Opierając się na opiniach użytkowników, chcemy dodatkowo ulepszyć komponent skryptu, aby obejmował dodatkowe przypadki użycia.

Poświadczenia

Dziękujemy Kary Erickson, Janicklas Ralph, Katie Hempenius, Philipa Waltona, Jeremy Wagnera i Addy Osmani za opinie na temat tego posta.