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, który wchodzi w skład aplikacji od razu po wczytaniu pierwszej strony, podzielenie go na kilka fragmentów przyspieszy działanie strony.

Z tego ćwiczenia w programie dowiesz się, jak za pomocą podziału kodu poprawić wydajność prostej aplikacji, która sortuje 3 liczby.

Okno przeglądarki z widoczną aplikacją o nazwie Magiczny sortownik z 3 polami do wpisania liczb i przyciskiem sortowania.

Zmierz odległość

Przed podjęciem jakichkolwiek działań optymalizacyjnych warto najpierw zmierzyć skuteczność witryny.

  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację, a potem Pełny ekran pełny ekran.
  2. Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
  3. Kliknij kartę Sieć.
  4. Zaznacz pole wyboru Wyłącz pamięć podręczną.
  5. Załaduj ponownie aplikację.

Panel sieci przedstawiający pakiet JavaScript o wielkości 71,2 KB.

JavaScript o wielkości 71,2 KB do posortowania kilku liczb w prostej aplikacji. Dlaczego?

W kodzie źródłowym (src/index.js) biblioteka lodash jest importowana i używana w tej aplikacji. Lodash oferuje wiele przydatnych funkcji narzędziowych, ale tutaj używana jest tylko jedna metoda z pakietu. Częstym błędem jest instalowanie i importowanie całych zależności zewnętrznych, gdy tylko ich niewielka część jest wykorzystywana.

Optymalizuj

Pakiet można skrócić na kilka sposobów:

  1. Utwórz niestandardową metodę sortowania zamiast importowania biblioteki zewnętrznej
  2. Aby posortować dane liczbowe, użyj wbudowanej metody Array.prototype.sort()
  3. Zaimportuj metodę sortBy tylko z usługi lodash, a nie z całej biblioteki
  4. Pobiera kod do sortowania dopiero wtedy, gdy użytkownik kliknie przycisk.

Opcje 1 i 2 to idealnie odpowiednie metody zmniejszenia rozmiaru pakietu (i prawdopodobnie sprawdzają się najlepiej w przypadku prawdziwej aplikacji). Nie są one jednak używane w tym samouczku do nauczania 😈.

Obie opcje pomagają zwiększyć wydajność tej aplikacji. Omówimy je w kilku kolejnych sekcjach tego ćwiczenia z programowania. Jak w przypadku każdego samouczka kodowania, zawsze staraj się napisać kod samodzielnie, zamiast kopiować i wklejać kod.

Importuj tylko to, czego potrzebujesz

Aby zaimportować z usługi lodash tylko jedną metodę, trzeba zmodyfikować kilka plików. Na początek zastąp tę zależność w 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";

Zaktualizuj też 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>
  `
});

Załaduj ponownie aplikację, otwórz Narzędzia deweloperskie i jeszcze raz przyjrzyj się panelowi Sieć.

Panel sieci przedstawiający pakiet JavaScript o wielkości 15,2 KB.

W tej aplikacji rozmiar pakietu został 4-krotnie zmniejszony przy niewielkim nakładzie pracy, ale wciąż można wprowadzić ulepszenia.

Podział kodu

webpack to jeden z najpopularniejszych obecnie pakietów oprogramowania open source. Krótko mówiąc, wszystkie moduły JavaScript (jak również inne zasoby) tworzące aplikację internetową łączą w pliki statyczne, które mogą odczytać przeglądarka.

Pojedynczy pakiet używany w tej aplikacji można podzielić na 2 osobne fragmenty:

  • Podmiot odpowiedzialny za kod stanowiący naszą początkową trasę
  • Dodatkowy fragment, który zawiera kod sortowniczy

Za pomocą importu dynamicznego dodatkowy fragment może być leniwy lub ładowany na żądanie. W tej aplikacji kod tworzący ten fragment można wczytać dopiero po naciśnięciu przycisku przez użytkownika.

Zacznij od usunięcia importu najwyższego poziomu dla metody sortowania w src/index.js:

import sortBy from "lodash.sortby";

Następnie zaimportuj go do detektora zdarzeń uruchamianego 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 na etapie 3 procesu TC39) obejmującej możliwość dynamicznego importowania modułu. Pakiet internetowy jest już obsługiwany i ma taką samą składnię, jaka została określona w ofercie pakietowej.

import() zwraca obietnicę, a gdy się zakończy, zostaje udostępniony wybrany moduł, który jest podzielony na osobny fragment. Po zwróceniu modułu atrybut module.default służy do odwoływania się do domyślnego eksportu udostępnianego przez lodash. Obietnica jest powiązana z innym elementem .then, który wywołuje metodę sortInput w celu sortowania 3 wartości wejściowych. Na końcu łańcucha obietnicycatch() służy do obsługi przypadków, w których obietnica została odrzucona z powodu błędu.

Ostatnią czynnością, jaką należy zrobić, jest zapisanie metody sortInput na końcu pliku. Musi to być funkcja, która zwraca funkcję korzystającą z zaimportowanej metody z metody lodash.sortBy. Zagnieżdżona funkcja może wtedy 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

Ponownie załaduj aplikację i jeszcze raz zwróć szczególną uwagę na panel Sieć. Od razu po wczytaniu aplikacji pobierany jest tylko mały wstępny pakiet.

Panel sieci przedstawiający pakiet JavaScript o wielkości 2,7 KB.

Po naciśnięciu przycisku w celu posortowania liczb wejściowych fragment zawierający kod sortowniczy jest pobierany i wykonywany.

Panel sieci przedstawiający pakiet JavaScript o wielkości 2,7 KB, a następnie pakiet JavaScript o wielkości 13,9 KB.

Zwróć uwagę, że liczby nadal są sortowane.

Podsumowanie

Dzielenie kodu i leniwe ładowanie to niezwykle przydatne techniki pozwalające ograniczyć początkowy pakiet aplikacji, a w rezultacie znacznie skrócić czas wczytywania strony. Jest jednak kilka ważnych kwestii, które należy wziąć pod uwagę przed uwzględnieniem optymalizacji w swojej aplikacji.

Interfejs leniwego ładowania

W przypadku leniwego ładowania określonych modułów kodu trzeba zastanowić się, jak będzie to działać w przypadku użytkowników mających słabsze połączenia sieciowe. Podzielenie i wczytanie bardzo dużego fragmentu kodu podczas przesyłania działania przez użytkownika może sprawić, że aplikacja przestanie działać. Warto więc pokazać jakiś rodzaj wskaźnika ładowania.

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

Nie zawsze jest to najlepsze podejście do leniwego wczytywania zależności innych firm w aplikacji i zależy od tego, gdzie ich używasz. Zależności innych firm są zwykle dzielone na oddzielny pakiet vendor, który można przechowywać w pamięci podręcznej, ponieważ nie aktualizują się tak często. Dowiedz się więcej o tym, jak może w tym pomóc SplitChunksPlugin.

Leniwe ładowanie za pomocą platformy JavaScript

Wiele popularnych platform i bibliotek korzystających z pakietu webpack udostępnia abstrakcje ułatwiające leniwe ładowanie niż korzystanie z dynamicznego importu w trakcie aplikacji.

Chociaż warto wiedzieć, jak działa importowanie dynamiczne, do leniwego wczytywania poszczególnych modułów zawsze używaj metody zalecanej przez Twoją platformę/bibliotekę.

Wstępne ładowanie i wstępne wczytywanie

W miarę możliwości korzystaj ze wskazówek dotyczących przeglądarki, takich jak <link rel="preload"> czy <link rel="prefetch">, aby szybciej wczytywać kluczowe moduły. Pakiet internetowy obsługuje obie wskazówki dzięki wykorzystaniu magicznych komentarzy w instrukcjach importu. Szczegółowo wyjaśniamy to w przewodniku Wstępnie wczytuj najważniejsze fragmenty.

Leniwe ładowanie nie tylko kodu

Obrazy mogą stanowić znaczną część aplikacji. Leniwe ładowanie tych, które znajdują się w części strony widocznej po przewinięciu lub poza widocznym obszarem urządzenia, może przyspieszyć działanie witryny. Więcej informacji na ten temat znajdziesz w przewodniku po leniwcach.