Wczytywanie dużych zasobów JavaScriptu znacząco wpływa na szybkość działania strony. Podział JavaScript na mniejsze fragmenty i pobierasz tylko to, co jest niezbędne aby strona działała podczas uruchamiania, może znacznie poprawić obciążenie strony responsywność strony, która z kolei może polepszyć interakcje z następną interakcją. Barwiony (INP).
Podczas pobierania, analizowania i kompilowania dużych plików JavaScript może dojść nie odpowiada przez dłuższy czas. Elementy strony są widoczne, ponieważ są są częścią początkowego kodu HTML strony i mają styl właściwy CSS. Ponieważ jednak kod JavaScript tych elementów interaktywnych – a także innych skryptów wczytywanych przez stronę – może to być np. analizowanie i wykonywanie kodu JavaScript w celu jej poprawnego funkcjonowania. może mieć wrażenie, że interakcja z nimi jest znacznie większa, z opóźnieniem, a nawet całkowicie uszkodzonych.
Dzieje się tak często, gdy wątek główny jest blokowany podczas analizowania JavaScriptu i zebrane w głównym wątku. Jeśli ten proces trwa zbyt długo, jest bardziej interaktywny elementy strony mogą nie reagować wystarczająco szybko na dane wejściowe użytkownika. Jedno rozwiązanie tego problemu to wczytywanie tylko tego kodu JavaScript, który jest niezbędny do działania strony, a odroczenie innych skryptów JavaScript do późniejszego załadowania za pomocą metody znanej jako kod dzielone na dwie części. W tej części skupimy się na drugiej z tych 2 technik.
Ogranicz analizowanie i wykonywanie JavaScriptu podczas uruchamiania dzięki podziałowi kodu
Lighthouse wyświetla ostrzeżenie, gdy wykonanie JavaScriptu trwa dłużej niż 2 razy i kończy się niepowodzeniem, jeśli trwa dłużej niż 3,5 sekundy. Nadmiarowy kod JavaScript analizowanie i wykonywanie tagów może być problemem w dowolnym miejscu strony, cyklu życia, ponieważ może to zwiększyć opóźnienia interakcji jeśli czas interakcji użytkownika ze stroną zbiega się z momentem główne zadania w wątku odpowiedzialnym za przetwarzanie i wykonywanie JavaScriptu są w domu.
Co więcej, nadmierne wykonywanie i analiza kodu JavaScript jest szczególnie problematyczny przy wstępnym wczytaniu strony, ponieważ to właśnie ten punkt cykl życia strony, który z dużym prawdopodobieństwem będzie korzystał z niej. Całkowity czas blokowania (TBT) – wskaźnik responsywności ładowania – jest silnie skorelowany. z wartością INP, co sugeruje, że użytkownicy mają tendencję do podejmowania prób interakcji podczas wstępnego wczytywania strony.
Audyt Lighthouse, który podaje czas poświęcony na wykonanie każdego pliku JavaScript żądania stron są przydatne, bo pomagają zidentyfikować skrypty mogą być wskazane do podziału kodu. Następnie możesz przejść dalej o korzystając z narzędzia do obudowy w Narzędziach deweloperskich w Chrome, aby zidentyfikować dokładnie te części JavaScript strony jest nieużywany podczas wczytywania strony.
Dzielenie kodu to przydatna technika, która pozwala zmniejszyć ilość początkowego JavaScriptu na stronie ładunki. Pozwala podzielić pakiet JavaScript na 2 części:
- JavaScript wymagany przy wczytywaniu strony, więc nie może zostać wczytany w żadnym innym miejscu obecnie się znajdujesz.
- Pozostały kod JavaScript, który można wczytać później, najczęściej w punkcie, w którym użytkownik wchodzi w interakcję z danym elementem interaktywnym stronę.
Kod można podzielić za pomocą składni dynamicznej import()
. Ten
składni – w przeciwieństwie do elementów <script>
, które wysyłają żądania dotyczące danego zasobu JavaScript.
podczas uruchamiania – wysyła żądanie o zasób JavaScript w późniejszym czasie podczas
cykl życia strony.
document.querySelectorAll('#myForm input').addEventListener('blur', async () => {
// Get the form validation named export from the module through destructuring:
const { validateForm } = await import('/validate-form.mjs');
// Validate the form:
validateForm();
}, { once: true });
W poprzednim fragmencie kodu JavaScript moduł validate-form.mjs
jest
pobrane, przeanalizowane i wykonane tylko wtedy, gdy użytkownik zamazuje dowolny
<input>
pól. W takiej sytuacji zasób JavaScript odpowiedzialny za
stosowanie logiki weryfikacji formularza jest uwzględniane na stronie tylko wtedy, gdy
są wykorzystywane najczęściej.
Pakiety JavaScript, takie jak webpack, Parcel, Rollup i esbuild, mogą być
skonfigurowane w taki sposób, aby dzielić pakiety JavaScript na mniejsze fragmenty, gdy
natrafisz w kodzie źródłowym na dynamiczne wywołanie import()
. Większość z tych narzędzi
jest to automatycznie, ale w szczególności tworzenie kodu wymaga włączenia tej opcji
optymalizacji.
Przydatne uwagi na temat dzielenia kodu
Dzielenie kodu jest skutecznym sposobem ograniczania rywalizacji o główne wątki już podczas jego początkowego wczytywania, warto pamiętać o kilku kwestiach. aby sprawdzić kod źródłowy JavaScript pod kątem możliwości podziału kodu.
Jeśli to możliwe, używaj kreatora pakietów
Zazwyczaj deweloperzy używają modułów JavaScript podczas jego rozwoju. To doskonałe rozwiązanie dla programistów, poprawia czytelność i łatwość obsługi kodu. Istnieją jednak pewne nieoptymalne cechy wydajności, które mogą wystąpić przy wysyłaniu kodu JavaScript. modułów do produkcji.
Przede wszystkim do przetwarzania i optymalizowania źródła należy korzystać z usług dostawcy pakietów włącznie z modułami, które mają zostać podzielone. Pakiety są bardzo skuteczne nie tylko optymalizowanie kodu źródłowego JavaScriptu, ale także pozwala na równoważenie czynników związanych z wydajnością, takich jak rozmiar pakietów ze współczynnikiem kompresji. Skuteczność kompresji zwiększa się wraz z rozmiarem pakietu, ale także starają się, by pakiety nie były tak duże, długie zadania ze względu na ocenę skryptu.
Pozwalają też na uniknięcie problemów z dostarczeniem dużej liczby rozłączonych modułów.
w sieci. Architektura wykorzystująca moduły JavaScriptu ma zwykle duże,
złożone drzewa modułów. Po rozgrupowaniu drzew modułów każdy moduł reprezentuje
osobne żądanie HTTP, dlatego interaktywność aplikacji internetowej może być opóźniona, jeśli
Nie łącz modułów w pakiety. Mimo że za pomocą atrybutu
Wskazówka dotycząca zasobu <link rel="modulepreload">
umożliwiająca szybkie wczytywanie dużych drzew modułów
ale pakiety JavaScript
są nadal lepsze od ładowania
z całego świata.
Nie wolno przez przypadek wyłączać kompilacji strumieniowania
Mechanizm JavaScript V8 w Chromium zapewnia wiele gotowych optymalizacji aby zapewnić jak najszybsze wczytywanie produkcyjnego kodu JavaScript. Jedna z takich optymalizacji nosi nazwę kompilacji strumieniowej, która – jak przyrostowa analiza składniowa kodu HTML przesyłanego do przeglądarki – kompiluje przesyłane strumieniowo fragmenty JavaScript pobieranych z sieci.
Aby upewnić się, że kompilacja strumieniowa będzie wykonywana w przypadku Twojego kanału, aplikacja internetowa w Chromium:
- Przekształć kod produkcyjny, aby uniknąć używania modułów JavaScript. Pakiety może przekształcić kod źródłowy JavaScript na podstawie celu kompilacji oraz cele są często powiązane z danym środowiskiem. V8 będzie stosować strumieniowanie do dowolnego kodu JavaScript, który nie korzysta z modułów, oraz skonfigurować pakiet usług tak, aby przekształcał kod modułu JavaScript w składnię który nie korzysta z modułów JavaScript ani ich funkcji.
- Jeśli chcesz przesłać moduły JavaScriptu do środowiska produkcyjnego, użyj metody
.mjs
. Niezależnie od tego, czy produkcyjny JavaScript używa modułów, brak specjalnego typu treści dla JavaScriptu, który korzysta z modułów w porównaniu z JavaScriptem. w przeciwnym razie. W przypadku V8 rezygnujesz ze strumieniowania danych podczas wysyłania modułów JavaScriptu w środowisku produkcyjnym za pomocą interfejsu.js
. Jeśli używasz rozszerzenia.mjs
dla modułów JavaScript, V8 może upewnij się, że kompilacja strumieniowa opartego na modułowym kodzie JavaScript nie działa.
Niech te kwestie zniechęcają Cię do dzielenia kodu. Koduj to skuteczny sposób ograniczania wstępnych ładunków JavaScriptu użytkowników, ale korzystając z narzędzia do tworzenia pakietów i dowiedzieć się, jak zachować kompilację, można zadbać o to, aby produkcyjny kod JavaScript dla użytkowników z myślą o użytkownikach.
Demonstracja importu dynamicznego
Webpack
webpack jest dostarczany z wtyczką o nazwie SplitChunksPlugin
, która umożliwia
skonfigurować sposób dzielenia plików JavaScript przez narzędzie pakietu. Webpack rozpoznaje zarówno
dynamiczne import()
i statyczne instrukcje import
. Działanie funkcji
SplitChunksPlugin
można zmodyfikować, określając opcję chunks
w
Konfiguracja:
chunks: async
to wartość domyślna i odnosi się do dynamicznych wywołańimport()
.- Parametr
chunks: initial
odnosi się do statycznych wywołań typuimport
. - Reguła
chunks: all
obejmuje zarówno import dynamicznyimport()
, jak i statyczny, dzięki czemu aby udostępnić fragmenty między importamiasync
iinitial
.
Domyślnie, gdy pakiet internetowy napotyka dynamiczną instrukcję import()
. jego
utworzy osobny fragment dla tego modułu:
/* main.js */
// An application-specific chunk required during the initial page load:
import myFunction from './my-function.js';
myFunction('Hello world!');
// If a specific condition is met, a separate chunk is downloaded on demand,
// rather than being bundled with the initial chunk:
if (condition) {
// Assumes top-level await is available. More info:
// https://v8.dev/features/top-level-await
await import('/form-validation.js');
}
W przypadku domyślnej konfiguracji pakietu internetowego dla poprzedniego fragmentu kodu powstaje 2 razy: (w osobnych częściach):
- Fragment
main.js
– który jest klasyfikowany jako fragmentinitial
– który zawiera modułymain.js
i./my-function.js
. - Fragment
async
, który zawiera tylkoform-validation.js
(zawierający hasz pliku w nazwie zasobu, jeśli został skonfigurowany). Ten fragment jest tylko pobrany czy i kiedycondition
jest prawdą.
Ta konfiguracja pozwala odroczyć wczytywanie fragmentu form-validation.js
do
jest naprawdę potrzebna. Może to poprawić szybkość ładowania dzięki ograniczeniu liczby skryptów
oceny podczas początkowego wczytywania strony. Pobieranie i ocena skryptu
dla fragmentu form-validation.js
występuje, gdy zostanie spełniony określony warunek, w polu
W takim przypadku pobrany zostanie moduł importowany dynamicznie. Przykładem może być
warunku, w którym element polyfill jest pobierany tylko dla określonej przeglądarki,
z wcześniejszego przykładu – zaimportowany moduł jest niezbędny do interakcji użytkownika.
Z drugiej strony zmień konfigurację SplitChunksPlugin
, aby określić
chunks: initial
zapewnia, że kod jest dzielony tylko na początkowych fragmentach. Są to
fragmentów, np. zaimportowanych statycznie lub wymienionych w elemencie entry
pakietu internetowego
usługi. W poprzednim przykładzie wynikowy fragment byłby
kombinacji form-validation.js
i main.js
w jednym pliku skryptu,
co może pogorszyć szybkość wczytywania strony na początku.
Opcje SplitChunksPlugin
można również skonfigurować tak, aby oddzielić większe
na kilka mniejszych, np. za pomocą opcji maxSize
instruowania pakietu internetowego, aby podzielić fragmenty na osobne pliki, jeśli przekroczą one limit
określona przez maxSize
. Dzielenie dużych plików skryptów na mniejsze
poprawić czas reagowania na obciążenie, ponieważ w niektórych przypadkach ocena skryptów obciążająca procesor
zadania są dzielone na mniejsze zadania, które rzadziej blokują główne zadania.
przez dłuższy czas.
Poza tym generowanie większych plików JavaScript oznacza również, że skrypty jest narażone na unieważnienie pamięci podręcznej. Na przykład jeśli wysyłasz bardzo duży skrypt z kodem platformy i własnej aplikacji, pakiet może zostać unieważniony, jeśli tylko platforma zostanie zaktualizowana, ale nic więcej w pakiecie.
Z drugiej strony mniejsze pliki skryptów zwiększają prawdopodobieństwo zwrotu użytkownik pobiera zasoby z pamięci podręcznej, dzięki czemu strony wczytują się szybciej do kolejnych wizyt. Jednak mniejsze pliki lepiej radzą sobie z kompresją niż większe. i może wydłużyć czas przesyłania danych w obie strony podczas wczytywania strony bez pamięci podręcznej przeglądarki. Zachowaj ostrożność, aby zachować równowagę między buforowaniem takich jak wydajność, wydajność kompresji i czas oceny skryptu.
wersja demonstracyjna pakietu webpack
demonstracja pakietu internetowego SplitChunksPlugin
.
Sprawdź swoją wiedzę
Który typ instrukcji import
jest używany podczas wykonywania kodu
podział?
import()
.import
.
Który typ instrukcji import
musi znajdować się na górze
modułu JavaScript i nie znajduje się w żadnym innym miejscu.
import()
.import
.
Jaka jest właściwość SplitChunksPlugin
w pakiecie internetowym?
różnica między fragmentem async
a fragmentem
initial
fragment?
async
fragmentu zostało wczytane za pomocą dynamicznej metody import()
i fragmenty (initial
) zostały wczytane przy użyciu elementów statycznych
import
async
fragmentu zostało wczytane przy użyciu statycznego parametru import
i fragmenty (initial
) są wczytywane za pomocą kreacji dynamicznych
import()
Następny krok: leniwe ładowanie obrazów i elementów <iframe>
Choć jest to dość drogi rodzaj zasobu, JavaScript nie jest
tylko taki typ zasobu, którego wczytywanie można odroczyć. Obraz i elementy <iframe>
same w sobie mogą być kosztownymi zasobami. Podobnie jak w przypadku JavaScriptu,
może opóźnić wczytywanie obrazów i elementu <iframe>
dzięki leniwemu ładowaniu
. Omówimy to w następnym module tego kursu.