Optymalizacja zasobów JavaScript pod kątem szybkości strony

Opublikowany: 2020-05-05

Poniższy przykład pochodzi z dużej, złożonej witryny informacyjnej. Od lat tracą ruch organiczny. Ich czas zdarzenia DOMContentLoaded wynosi 2615,2 MS. Możesz pomyśleć, że ich rozmiar DOM jest bardzo duży, ale nie…

Jest prawie taki sam, jak zaleca Google, a w tym dokumencie istnieje tylko 1230 węzłów HTML.

Możesz obliczyć czas i przebieg zdarzenia domContentLoaded oraz porównać je z konkurencją za pomocą DevTools.

Analiza tego przykładu pokazuje, że rozmiar DOM niekoniecznie jest punktem krytycznym. Tutaj głównym problemem jest kolejność zasobów : niebieskie części w „Głównej karcie” służą do analizowania kodu HTML. Jednak ta strona internetowa przerywa przeglądarkę z renderowaniem JavaScript przed zakończeniem procesu parsowania HTML.

(Możesz również skorzystać z sekcji Drzewo połączeń, aby znaleźć podobne błędy dla swojego zespołu IT.)

Ten przykład jasno ilustruje znaczenie optymalizacji zasobów JavaScript i tego, co może się nie udać, gdy pominiesz JavaScript w optymalizacji szybkości strony.

To trzeci z serii czterech artykułów. Aby lepiej zrozumieć ten artykuł, możesz przeczytać dwa pierwsze artykuły z tej serii:

  • Renderowanie JavaScript i szybkość strony są ściśle związane z tym, jak silnik renderujący przeglądarki tworzy stronę internetową.
  • Zanim przejdziesz do tego artykułu, powinieneś również zrozumieć zaawansowane metryki szybkości strony.

Posłużę się kilkoma przykładami z pierwszych dwóch artykułów, aby przedstawić kontekst w tym artykule.

Co to jest renderowanie JavaScript i jak wpływa na szybkość Twojej strony?

Renderowanie JavaScript to ostatnia sekcja ładowania strony, która może interaktywnie zmieniać strukturę utworzoną za pomocą DOM i CSSOM. Każdy element strony można zmienić w formacie wyzwalanym przez użytkownika lub wyświetlać w normalny sposób. Każdy element z właściwością display:none, do którego nie można było uzyskać dostępu z drzewa renderowania, może być renderowany jako widoczny za pomocą JavaScript lub wstrzykiwany za pośrednictwem różnych elementów HTML do DOM.

JavaScript przerywa DOM i CSSOM, ponieważ zmienia DOM i CSSOM w momencie ich odczytania przez przeglądarkę. Dlatego, aby nie wpłynąć negatywnie na czas i szybkość ładowania strony, konieczne jest zbadanie relacji między renderowaniem DOM, CSSOM i JavaScript.

Powyżej znajduje się przykład drzewa renderowania. Wszystkie blokujące fragmenty kodu w węzłach CSSOM i HTML mają semantyczne odpowiedniki w drzewie renderowania. Jeśli przyjrzysz się uważnie, zauważysz, że węzeł HTML „Przycisk akcji” nie znajduje się w drzewie renderowania. Głównym tego powodem jest „display:none”; Właściwość CSS. Z powodu tego polecenia niewidzialności nie jest ono uwzględnione w drzewie renderowania. Aby zobaczyć, jak zostały zbudowane elementy tego drzewa, możesz przeczytać pierwszy artykuł z tej serii.

Jeśli masz wiele elementów strony, które nie pojawią się przy pierwszym załadowaniu, ponieważ zależą od zachowania użytkownika, w kolejności ładowania zasobów będziesz musiał oddzielić te elementy i umieścić je w ostatnim wierszu. W tym momencie lepszym rozwiązaniem jest użycie shadow DOM lub wirtualnego DOM.

Atrybuty Defer i Async dla zasobów JavaScript

Jeśli umieścisz pliki JS w sekcji i nie użyjesz atrybutów „defer” lub „async”, prawdopodobnie opóźni to czas DOMContentLoaded. Aby temu zapobiec, możemy wykorzystać te dwa atrybuty. Defer ma opóźnić proces ładowania pliku JS, podczas gdy „Async” ma ładować JS i inne źródła w równoległy sposób. Oba mają zalety i wady. Porozmawiamy tutaj tylko o najważniejszych.

  • Jeśli użyjesz defer na głównym pliku JS, prawdopodobnie nie zobaczysz jego efektów „inicjatora”, dopóki nie zostanie zainstalowany.
  • Jeśli użyjesz odroczenia zbyt dużo, możesz spowodować wąskie gardło procesora pod koniec ładowania strony.

Od czasu napisania tego artykułu została wydana aktualizacja Chrome 80. W kolumnie Inicjator znacznie łatwiej jest teraz zobaczyć, który zasób jest wywoływany przez który zasób. Na przykład możesz zobaczyć obraz lub plik CSS wywoływany przez JS. Jeśli przewiniesz zasoby, przytrzymując klawisz Shift, zobaczysz również, którego zasobu nie można użyć bez załadowania innych zasobów.

Przewijanie przy wciśniętym klawiszu Shift: kolor czerwony wskazuje zasób warunkowy dla zasobu podświetlonego na zielono.

Możesz też skorzystać z nowej sekcji Inicjator w Chrome, aby uzyskać bardziej szczegółową kolejność ładowania zasobów, inicjatora i sprawdzanie priorytetów. Pozwala to wykryć wyjątkowo długie i kosztowne łańcuchy połączeń JS, takie jak ten poniżej.

Przykład długiego i kosztownego łańcucha połączeń JS z tej samej witryny. Nad wybranym zasobem znajdują się jego inicjatorzy. Kolejna część przedstawia zasoby zainicjowane przez wybrany zasób.

  • Odroczone pliki JS są pobierane po zdarzeniu domInteractive, więc musisz je wybrać zgodnie z plikami CSS i obrazami.
  • Jeśli odłożysz niektóre pliki JS innych firm do śledzenia użytkowników, możesz nie być w stanie śledzić niektórych zachowań użytkowników.
  • Odroczenie zwykle nie blokuje procesu DOM, ale robi to Async. Pliki JS z atrybutami asynchronicznymi są pobierane przez przeglądarkę podczas analizowania kodu HTML i przetwarzania CSSOM.
  • Jeśli użyjesz atrybutu async zbyt często, prawdopodobnie utworzysz wąskie gardło przetwarzania procesora, a także spowolnisz procesy DOM i CSSOM. Musisz ostrożnie wybrać, co odroczyć lub zsynchronizować.

Oto przykładowy schemat atrybutów asynchronicznych i odroczonych. Pierwszy z nich jest ładowany przed domContentLoaded bez dzielenia parsowania HTML podczas pobierania. W drugim pobrany plik JS nie jest wykonywany przed zakończeniem parsowania HTML.

Sugestie i wskazówki dotyczące renderowania i wydajności JavaScript

Zanim przejdziesz do praktycznych przykładów, oto kilka sugestii, jak poprawić wydajność renderowania JavaScript. Może to również pomóc w lepszym zrozumieniu szybkości strony i sposobu działania przeglądarki.

Nie używaj niepotrzebnych zmiennych.

Jeśli jesteś SEO, możesz zauważyć niepotrzebne lub nieużywane zmienne w pliku JavaScript. Istnieje wiele narzędzi, które można wykorzystać do wykrycia tego rodzaju błędu. Poniżej znajdziesz dwa podstawowe przykłady nieużywanych i niepotrzebnych zmiennych.

var carName= marka+ ” ” + rok;
document.getElementById(“demo”).innerHTML = carName;

Tutaj zmienna „carName” jest niepotrzebna. Możesz zaproponować następującą modyfikację:
document.getElementById(„demo”).innerHTML = marka+ ” ” + rok

Lub:

[a, b, c, d, e].forEach(funkcja (wartość, indeks) {
console.log(indeks);
});

Tutaj parametr „wartość” nie jest konieczny, ponieważ nie jest używany. Możesz go usunąć:
[a, b, c, d, e].forEach(funkcja (indeks) {
console.log(indeks);
});

Po prawej stronie widać dłuższe czasy połączenia (białe linie), a pliki CSS i JS są ładowane w asymetrycznej kolejności dzięki „async” JavaScript.

Po lewej stronie czasy połączenia są krótsze, a pliki CSS i JS nie są mieszane, ponieważ każde źródło jest ładowane w wierszach. Atrybuty asynchroniczne mogą zmniejszyć indeks szybkości, ponieważ może wydłużyć czas TBT, więc musisz przeprowadzić dochodzenie i zgłosić to zespołowi programistów w celu uzyskania plików JS śledzenia wydajności z karty wydajności lub możesz samodzielnie przeprowadzić eksperymenty.

Używaj narzędzi do trudnych zadań

Dla początkującego w kodzie znalezienie niepotrzebnych lub nieużywanych zmiennych może być trudne. Do tych zadań możesz użyć niektórych narzędzi, takich jak pakiety Chrome DevTools lub Node.js, takie jak Unused (Kami/node-unused: moduł, który zgłasza zdefiniowane, ale nieużywane zmienne w kodzie lub więcej nieużywanych zmiennych). Jeśli znajdziesz nawet drobne błędy, wierzę, że Twój zespół IT wysłucha Cię za ulepszanie plików JavaScript.

Korzystanie z raportu dotyczącego Chrome DevTools w celu znalezienia nieużywanego kodu JavaScript

Chrome DevTools Coverage Report pokazuje niewykorzystane fragmenty kodu JavaScript, ale nie jest to zbyt praktyczne. Możesz pomyśleć, że możesz usunąć każdą czerwoną część kodu, ale tak nie jest… Zamiast tego powinieneś znaleźć zupełnie nieużywane funkcje lub zmienne dla dużej liczby stron kategorii. W ten sposób Twój zespół programistów może zostać przekonany do użycia procesu TreeShaking.

TreeShaking oznacza usuwanie martwego kodu z plików. Aby zyskać na czasie, polecam uczyć się z wykorzystaniem nieużywanych zmiennych JS i pakietów wyszukiwania funkcji.

Mniejszy rozmiar DOM pomoże również w renderowaniu JavaScript. Każde polecenie (getElementsByTagName) przeskanuje Twój DOM. Mniejszy rozmiar DOM będzie wymagał mniej zasobów przeglądarki i procesora/sieci urządzenia podczas renderowania JavaScript.

Wraz z nową aktualizacją Chrome 80 zmienił się również raport pokrycia. Dodali opcjonalne opcje Per Function i Per Block. Wartość domyślna jest tutaj na blok.

Jeśli wybierzesz opcję Według funkcji, zobaczysz dużą różnicę w swoim raporcie. Głównym powodem tej sytuacji jest to, że widok Per Function sprawdza, czy wszystkie funkcje są używane, czy nie. Jeśli używane jest 95% funkcji, opcja Per Function zdefiniuje ją jako nieużywany kod, ponieważ 5% kodu nie jest używane, chociaż używana jest większość funkcji.

Kompresuj, Minifikuj lub Uglify swoje pliki JS.

Można to zrobić na dwa sposoby. Najpierw usuń spacje i niepotrzebne komentarze. Po drugie, użyj ulepszonych operatorów JavaScript dla swoich plików JS i nazw, zmiennych, funkcji z gotowymi technologiami.

Powinieneś wiedzieć o funkcjach strzałek dla tego rodzaju kompresji. Na przykład zamiast tego 84-znakowego przykładu:

strzałka funkcji Islev (a, b) {
console.log (a + b);
}
arrowFonksiyon (5, 6);

Możesz skompresować go do 50 znaków za pomocą funkcji strzałek =>
const ab = (a, b) => b + a;
console.log (ab (5, 6));

Inna metoda skracania/kompresowania jest odpowiednia dla instrukcji If. Zamiast tego fragmentu kodu zawierającego 63 znaki:
jeśli (a<b) {
console.log(ab);
}
w przeciwnym razie {
konsola.log(a+b);

Możesz użyć tego z 43 znakami poniżej:
(a<b) ? console.log(ab) : console.log(a+b);

Możesz również zasugerować swojemu zespołowi IT, aby używał znaków $ i _ do kompresji. Większość plików JavaScript działa w celu reinterpretacji DOM. Do tego możesz zobaczyć wiele document.getElementById(x); fragmenty kodu w plikach. Do tego zadania możesz użyć znaku $. To uratuje cię przed ogromnym stosem bezużytecznych rozmiarów.

Większość bibliotek JavaScript domyślnie używa $ do definicji funkcji, ale nie wszystkie, ponieważ $ jest również znakiem alfabetu.

W takiej sytuacji możesz zasugerować, aby Twój zespół IT wykorzystał:
function $(x) {return document.getElementById(x);} .

Użyj odpowiedniego typu renderowania

Typy renderowania stron JavaScript i stron internetowych pod kątem zgodności z SEO.
SSR Hydration oznacza, że ​​niektóre komponenty JS zostaną wyrenderowane przy użyciu renderowania po stronie klienta. Jest to przydatne dla FP i FMP, ale mogą być pewne wady dla wyników TTI i Speed ​​Index.
Źródło obrazu: Notprovided.eu

Najlepsze praktyki kodowania dotyczące wydajności renderowania JavaScript

  • Kolejny ważny wkład w kompresję będzie pochodził z użycia „_”. Możesz użyć „underscore.js”, aby poprawić formaty i funkcje pisania JavaScript. W ten sposób utworzysz mniejsze pliki JS, jednocześnie manipulując listami i kolekcjami z krótszymi funkcjami JS bez wbudowanych funkcji JS.
  • Używanie wielu długich i wyczerpujących zmian zmiennych oraz zanieczyszczenia zmiennych globalnych jest również źródłem powolnego renderowania. Powinieneś określić ogólne wybory zakresu swoich funkcji oraz typy zmiennych globalnych/długich. Używanie zmiennych lokalnych z „Let” jest lepsze do renderowania. Ze względu na zmienne lokalne przeglądarki nie będą kontrolować innych globalnych zmiennych funkcji pod kątem następnej zmiany.

Aby zasymulować bardziej realistyczne badanie wydajności, na przykład to, co możesz zobaczyć na słabszych telefonach komórkowych, użyj preferencji ograniczania procesora i szybkiego/wolnego połączenia 3G w Chrome DevTools.
Źródło obrazu: Addy Osmani

  • Korzystanie z mniejszych funkcji JS i łańcuchów zmiennych poprawi wydajność renderowania. Dodatkowo, używanie selektora „tego” zamiast selektora „z” jest lepsze. Selektor „Ten” w JavaScript jest kodem działającym lokalnie, w przeciwieństwie do „with”, ta sama logika z let i var jest również tutaj poprawna.
  • Jeśli użyjesz swoich instrukcji we fragmentach kodu pętli For, to również spowolni nieco szybkość renderowania. Ponieważ twoja instrukcja funkcji będzie iterować przez każdy element pętli. Możesz po prostu utworzyć nową zmienną dla elementów pętli i możesz wywołać te elementy za pomocą funkcji, która jest poza pętlą For.
  • Jeśli chcesz kilkakrotnie dotrzeć do elementu HTML, możesz utworzyć dla niego zmienną i wywołać go za pomocą funkcji, które chcesz. Dotarcie do elementu HTML za pomocą JavaScript nie jest szybkim procesem. Możesz po prostu stworzyć większe obciążenie dla swojej przeglądarki.

Innym sposobem na poprawę wydajności renderowania JavaScript jest renderowanie trizomorficzne za pośrednictwem Service Workerów. Możesz umieścić niektóre pliki JS w pamięci przeglądarki klienta na potrzeby przyszłych sesji. W ten sposób możesz sprawić, że Twoja witryna będzie działać w trybie offline.
Tutaj znajdziesz proste demo, aby lepiej zrozumieć i poćwiczyć z pracownikami serwisu

Wiązanie się: jak optymalizacja JavaScriptu i szybkości strony wpływa na SEO

Aby zapobiec sabotowaniu szybkości strony przez zasoby JavaScript, widzieliśmy, jak odroczenie i asynchronia mogą mieć ogromne znaczenie. Przyjrzeliśmy się również kilku strategiom „debugowania” i wskazówkom dotyczącym kodowania, które mogą pomóc w zwiększeniu szybkości stron z zasobami JavaScript.

Teraz, gdy widzieliśmy, w jaki sposób przeglądarki budują strony internetowe, w jaki sposób mierzona jest szybkość strony i jak wpływa na nią, oraz rolę, jaką optymalizacja JavaScript odgrywa w czasie ładowania strony, następny artykuł pokaże, jak kolejność ładowania zasobów wpływa na szybkość strony i budżet indeksowania.

Jeśli chcesz przejrzeć poprzednie artykuły z tej serii czterech artykułów, możesz je znaleźć tutaj:

  • „Jak przeglądarka tworzy stronę internetową”
  • „Zaawansowane wskaźniki szybkości strony”.
Rozpocznij darmowy okres próbny