Większość stron internetowych i aplikacji składa się z wielu różnych części. Zamiast wysyłać cały kod JavaScript, z którego składa się aplikacja, zaraz po załadowaniu pierwszej strony, podziel kod JavaScript na kilka części, aby zwiększyć wydajność strony.
Ten warsztat programistyczny pokazuje, jak za pomocą dzielenia kodu poprawić wydajność prostej aplikacji, która sortuje 3 liczby.
Zmierz odległość
Jak zawsze, zanim zaczniesz optymalizować witrynę, musisz najpierw sprawdzić, jak ona działa.
- 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 Disable cache (Wyłącz pamięć podręczną).
- Przeładuj aplikację.
71,2 KB kodu JavaScript tylko po to, aby posortować kilka liczb w prostej aplikacji. Dlaczego?
W kodzie źródłowym (src/index.js
) biblioteka lodash
jest importowana i używana w tej aplikacji. Lodash udostępnia wiele przydatnych funkcji, ale tutaj używana jest tylko jedna metoda z tego pakietu.
Instalowanie i importowanie całych zależności zewnętrznych, z których wykorzystywana jest tylko niewielka część, to częsty błąd.
Optymalizuj
Rozmiar pakietu można zmniejszyć na kilka sposobów:
- Zamiast importować bibliotekę zewnętrzną, możesz napisać niestandardową metodę sortowania.
- Użyj wbudowanej metody
Array.prototype.sort()
do sortowania numerycznego. - Importuj tylko metodę
sortBy
zlodash
, a nie całą bibliotekę. - Pobierz kod sortowania tylko wtedy, gdy użytkownik kliknie przycisk
Opcje 1 i 2 to odpowiednie metody zmniejszania rozmiaru pakietu (i prawdopodobnie będą najbardziej odpowiednie w przypadku rzeczywistego zastosowania). W tym samouczku nie są one jednak używane ze względu na charakter tego poradnika. 😈
Zarówno opcja 3, jak i opcja 4 pomagają poprawić wydajność tej aplikacji. Te kroki są opisane w kolejnych sekcjach tego ćwiczenia. Podobnie jak w przypadku każdego samouczka programistycznego, zawsze staraj się pisać kod samodzielnie, zamiast kopiować i wklejać.
Importuj tylko te dane, których potrzebujesz
Aby zaimportować tylko jedną metodę z lodash
, trzeba zmodyfikować kilka plików.
Na początek zastąp tę zależność w pliku package.json
:
"lodash": "^4.7.0",
z tym:
"lodash.sortby": "^4.7.0",
Teraz w src/index.js
zaimportuj ten konkretny moduł:
import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";
Zmień sposób sortowania wartości:
form.addEventListener("submit", e => {
e.preventDefault();
const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
const sortedValues = _.sortBy(values);
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
});
Ponownie załaduj aplikację, otwórz Narzędzia deweloperskie i jeszcze raz spójrz na panel Sieć.
W przypadku tej aplikacji rozmiar pakietu został zmniejszony ponad 4-krotnie przy niewielkim nakładzie pracy, ale nadal można go jeszcze zmniejszyć.
Dzielenie kodu
webpack to jedno z najpopularniejszych obecnie pakietujących modułów open source. Krótko mówiąc, zbiera wszystkie moduły JavaScript (oraz inne zasoby), które tworzą aplikację internetową, w pliki statyczne, które mogą być odczytywane przez przeglądarkę.
Pojedynczy pakiet używany w tej aplikacji można podzielić na 2 oddzielne części:
- Jeden odpowiada za kod, który tworzy naszą początkową trasę.
- Drugi fragment zawierający kod sortowania
Dzięki importom dynamicznym można wczytywać drugi fragment leniwie lub na żądanie. W tej aplikacji kod, z którego składa się fragment, może zostać wczytany tylko wtedy, gdy użytkownik naciśnie przycisk.
Zacznij od usunięcia importu na najwyższym poziomie dla metody sortowania w pliku src/index.js
:
import sortBy from "lodash.sortby";
Zaimportuj go w detektorze zdarzeń, który jest uruchamiany po naciśnięciu przycisku:
form.addEventListener("submit", e => {
e.preventDefault();
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
Funkcja import()
jest częścią propozycji (obecnie w etapie 3 procesu TC39) dotyczącej dodania możliwości dynamicznego importowania modułu. webpack obsługuje już tę funkcję i korzysta z tej samej składni, która została opisana w propozycji.
import()
zwraca obietnicę, która po wykonaniu zwraca wybrany moduł podzielony na osobny fragment. Po zwróceniu modułu zmienna module.default
jest używana do odwoływania się do domyślnego eksportu udostępnianego przez lodash. Obietnica jest połączona z inną funkcją .then
, która wywołuje metodę sortInput
, aby posortować 3 wartości wejściowe. Na końcu łańcucha obietnic.catch()
służy do obsługi przypadków, w których obietnica zostaje odrzucona z powodu błędu.
Ostatnią rzeczą, którą należy zrobić, jest zapisanie metody sortInput
na końcu pliku. Musi to być funkcja, która zwraca funkcję przyjmującą zaimportowaną metodę z lodash.sortBy
. Funkcja zagnieżdżona może następnie posortować 3 wartości wejściowe i zaktualizować DOM.
const sortInput = () => {
return (sortBy) => {
const values = [
input1.valueAsNumber,
input2.valueAsNumber,
input3.valueAsNumber
];
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
};
}
Monitorowanie
Załaduj aplikację jeszcze raz i ponownie uważnie obserwuj panel Sieć. Gdy aplikacja się wczytuje, pobierany jest tylko mały pakiet początkowy.
Gdy naciśniesz przycisk sortowania danych wejściowych, fragment kodu sortowania zostanie pobrany i wykonany.
Zwróć uwagę, że liczby są nadal sortowane.
Podsumowanie
Dzielenie kodu i opóźnione wczytywanie mogą być bardzo przydatnymi technikami pozwalającymi zmniejszyć początkowy rozmiar pakietu aplikacji, co może bezpośrednio przełożyć się na znacznie szybsze wczytywanie stron. Zanim uwzględnisz tę optymalizację w swojej aplikacji, musisz jednak wziąć pod uwagę kilka ważnych kwestii.
Leniwe ładowanie interfejsu
Podczas ładowania poszczególnych modułów kodu z opóźnieniem należy wziąć pod uwagę, jak będzie to wyglądać w przypadku użytkowników z słabszym połączeniem z siecią. Dzielenie i wczytywanie bardzo dużego fragmentu kodu, gdy użytkownik wykonuje jakąś czynność, może sprawiać wrażenie, że aplikacja przestała działać. Dlatego warto wyświetlać jakiś wskaźnik wczytywania.
Leniwe ładowanie modułów węzła innych firm
W zależności od miejsca użycia w aplikacji nie zawsze warto stosować opóźnione wczytywanie zależności zewnętrznych. Zwykle zależności zewnętrzne są dzielone na osobne pakiety vendor
, które można przechowywać w pamięci podręcznej, ponieważ nie są aktualizowane tak często. Dowiedz się więcej o tym, jak w tym pomóc może wtyczka SplitChunksPlugin.
Leniwe ładowanie za pomocą platformy JavaScript
Wiele popularnych frameworków i bibliotek korzystających z webpacka zapewnia abstrakcje, które ułatwiają opóźnione wczytywanie w porównaniu z użyciem dynamicznych importów w aplikacji.
- Leniwe ładowanie modułów w Angularze
- Dzielenie kodu za pomocą React Router
- Leniwe ładowanie za pomocą Vue Router
Chociaż warto wiedzieć, jak działają importy dynamiczne, zawsze używaj metody zalecanej przez framework lub bibliotekę do leniwego wczytywania określonych modułów.
Wstępne ładowanie i pobieranie z wyprzedzeniem
W miarę możliwości korzystaj z wskazówek przeglądarki, takich jak <link rel="preload">
lub <link rel="prefetch">
, aby szybciej wczytywać ważne moduły. webpack obsługuje oba te wskazówki za pomocą magicznych komentarzy w instrukcjach importu. Szczegółowe informacje na ten temat znajdziesz w przewodniku Przelewanie kluczowych fragmentów.
Leniwe ładowanie nie tylko kodu
Obrazy mogą stanowić istotną część aplikacji. Leniwe ładowanie tych, które znajdują się poniżej linii łamu lub poza widocznym obszarem urządzenia, może przyspieszyć działanie witryny. Więcej informacji znajdziesz w przewodniku Lazysize.