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 JavaScriptu, który tworzy aplikację, zaraz po wczytaniu pierwszej strony, podzielenie go na kilka fragmentów poprawia wydajność strony.

Z tego ćwiczenia w Codelabs dowiesz się, jak używać dzielenia kodu, aby 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 spróbujesz wprowadzić optymalizacje, najpierw sprawdź skuteczność strony.

  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekranpeł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. Ponownie zał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 narzędziowych, ale używana jest tylko jedna metoda z 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). Nie są one jednak używane w tym samouczku tylko ze względu na nauczanie 😈.

Obie opcje 3 i 4 pomagają zwiększyć wydajność 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 to, czego 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",

tym:

"lodash.sortby": "^4.7.0",

Teraz w aplikacji 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 można jeszcze udoskonalić.

Dzielenie kodu

Webpack to jedno z najpopularniejszych obecnie używanych narzędzi do tworzenia pakietów 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 importowaniu dynamicznemu fragment dodatkowy można ładować 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.

Najpierw usuń import najwyższego poziomu dla metody sortowania w src/index.js:

import sortBy from "lodash.sortby";

Zaimportuj go w detektorze zdarzeń, który uruchamia się 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ą oferty pakietowej (obecnie na etapie 3 procesu TC39), która obejmuje możliwość dynamicznego importowania modułu. Webpack już obsługuje tę funkcję i ma taką samą składnię jak w ofercie pakietowej.

import() zwraca obietnicę, która po spełnieniu warunków 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ą, jaką musisz 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 przyjrzyj się panelowi 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 zawierający kod 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 nadal są sortowane.

Podsumowanie

Dzielenie kodu i leniwe ładowanie mogą być bardzo przydatnymi technikami ograniczania początkowego rozmiaru pakietu aplikacji, co może bezpośrednio przełożyć się na znacznie szybsze wczytywanie stron. Zanim jednak uwzględnisz tę optymalizację w swojej aplikacji, musisz wziąć pod uwagę kilka ważnych kwestii.

Leniwe ładowanie interfejsu

W przypadku leniwego ładowania określonych modułów kodu należy zastanowić się, jak będzie działać w przypadku użytkowników ze słabszymi połączeniami sieciowymi. Dzielenie i wczytywanie bardzo dużego fragmentu kodu, gdy użytkownik podejmuje działanie, może sprawiać wrażenie, że aplikacja przestała działać. Warto więc wyświetlić jakiś wskaźnik wczytywania.

Leniwe ładowanie modułów węzła innych firm

W przypadku niektórych aplikacji nie zawsze warto stosować opóźnione wczytywanie zależności zewnętrznych. Wszystko zależy od tego, gdzie ich używasz. 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 SplitChunksPlugin.

Leniwe ładowanie za pomocą platformy JavaScript

Wiele popularnych frameworków i bibliotek korzystających z webpacka udostępnia abstrakcje, które ułatwiają opóźnione wczytywanie w sposób łatwiejszy niż używanie 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 wczytywanie 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ółowo wyjaśniliśmy to w przewodniku Wstępne wczytywanie 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.