Ogranicz ładunki JavaScript dzięki podziałowi kodu

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.

W oknie przeglądarki wyświetla się aplikacja o nazwie Magic Sorter z 3 polami do wprowadzania liczb i przyciskiem sortowania.

Zmierz odległość

Jak zawsze, zanim zaczniesz optymalizować witrynę, musisz najpierw sprawdzić, jak ona działa.

  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran pełny ekran.
  2. Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
  3. Kliknij kartę Sieć.
  4. Zaznacz pole wyboru Disable cache (Wyłącz pamięć podręczną).
  5. Przeładuj aplikację.

Panel sieciowy pokazujący pakiet JavaScript o długości 71,2 KB.

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:

  1. Zamiast importować bibliotekę zewnętrzną, możesz napisać niestandardową metodę sortowania.
  2. Użyj wbudowanej metody Array.prototype.sort() do sortowania numerycznego.
  3. Importuj tylko metodę sortBy z lodash, a nie całą bibliotekę.
  4. 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ć.

Panel sieciowy pokazujący pakiet JavaScript o długości 15,2 KB.

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.

Panel sieciowy pokazujący pakiet JavaScript o rozmaju 2,7 KB.

Gdy naciśniesz przycisk sortowania danych wejściowych, fragment kodu sortowania zostanie pobrany i wykonany.

Panel sieciowy pokazujący pakiet kodu JavaScript o rozmiarze 2,7 KB, a za nim pakiet kodu JavaScript o rozmiarze 13,9 KB.

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.

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.