Wstępnie wczytuj moduły

Sérgio Gomes

Programowanie oparte na modułach ma pewne zalety w zakresie buforowania, pomagając w zmniejszeniu liczby bajtów, które muszą być wysyłane do użytkowników. Większa szczegółowość kodu ułatwia też wczytywanie historii, ponieważ nadaj priorytet krytycznemu kodowi w aplikacji.

Jednak zależności modułów stwarzają problem z wczytywaniem, ponieważ przeglądarka musi musi poczekać, aż moduł się załaduje, zanim ustali jego zależności. W jedną stronę jest wstępne wczytywanie zależności, dzięki czemu przeglądarka wie pliki z wyprzedzeniem i mogą utrzymać połączenie.

<link rel="preload"> to sposób na deklaratywną prośbę o zasoby z wyprzedzeniem, zanim przeglądarka będzie ich używać.

<head>
  <link rel="preload" as="style" href="critical-styles.css">
  <link rel="preload" as="font" crossorigin type="font/woff2" href="myfont.woff2">
</head>

Obsługa przeglądarek

  • Chrome: 50.
  • Krawędź: ≤ 79.
  • Firefox: 85.
  • Safari: 11.1

Źródło

Sprawdza się to szczególnie w przypadku takich zasobów jak czcionki, które są często ukryte. w plikach CSS, czasami nawet na kilku poziomach. W takiej sytuacji przeglądarka musieliby zaczekać na kilka lotów w obie strony, zanim dowie się, że musi pobrać duży plik czcionek, jeśli można wykorzystać ten czas na rozpoczęcie pobierania. i korzystać z pełnej przepustowości łącza.

Komponent <link rel="preload"> i jego odpowiednik w nagłówku HTTP zapewniają prosty, deklaratywny sposób poinformowania przeglądarki o kluczowych plikach, które będą potrzebne jako część bieżącej nawigacji. Gdy przeglądarka wykryje wstępne wczytanie, zacznie priorytetowego pobierania zasobu, dzięki czemu, gdy będzie on potrzebny, zostały już pobrane lub są dostępne częściowo. Nie działa jednak w przypadku modułów.

Tutaj sprawy stają się trudniejsze. Istnieje kilka trybów dostępu do danych logowania zasobów. Aby uzyskać trafienie w pamięci podręcznej, muszą one do siebie pasować. W przeciwnym razie zostaną dwukrotnie pobiera zasób. Podwójne pobieranie jest oczywiście złe, marnuje przepustowość sieci użytkownika i nie bez powodu czeka dłużej.

W przypadku tagów <script> i <link> tryb danych logowania można ustawić za pomocą parametru crossorigin . Okazuje się jednak, że element <script type="module"> bez Atrybut crossorigin wskazuje tryb danych logowania omit, który nie istnieje za <link rel="preload">. Oznacza to, że konieczne będzie zmień atrybut crossorigin w <script> i <link> na 1 innych wartości. Nie jest łatwo, jeśli próba wstępnego załadowania zależy od innych modułów.

Co więcej, pobranie pliku to tylko pierwszy krok do faktycznego uruchomienia kodu. Najpierw przeglądarka musi ją przeanalizować i skompilować. Najlepiej, też należy to zrobić z wyprzedzeniem, aby, gdy moduł był potrzebny, kod został gotowe do uruchomienia. Jednak V8 (mechanizm JavaScript w Chrome) analizuje i kompiluje moduły inaczej niż w przypadku innego JavaScriptu. <link rel="preload"> nie nie pozwalają w żaden sposób wskazać, że wczytywany plik jest modułem, tak by cała przeglądarka tylko załadować plik i umieścić go w pamięci podręcznej. Po wczytaniu skryptu za pomocą <script type="module"> (lub został wczytany przez inny moduł), przeglądarka analizuje i skompiluje kod jako moduł JavaScript.

Krótko mówiąc, tak. Mając określony typ link do wstępnego wczytywania modułów, napisać prosty kod HTML, nie martwiąc się o tryb danych logowania. ustawienia domyślne po prostu działają.

<head>
  <link rel="modulepreload" href="super-critical-stuff.mjs">
</head>
[...]
<script type="module" src="super-critical-stuff.mjs">

Przeglądarka wie już, że wstępnie wczytywany moduł to moduł, więc można oraz przeanalizowanie i skompilowanie modułu zaraz po pobraniu, zamiast czekać. aż spróbuje się uruchomić.

Obsługa przeglądarek

  • Chrome: 66.
  • Krawędź: ≤ 79.
  • Firefox: 115.
  • Safari: 17.

Źródło

A co z modułami, zależności?

Ciekawe, o to pytasz! Rzeczywiście nie ma czegoś takiego jak rekurencja.

Specyfikacja <link rel="modulepreload"> pozwala na opcjonalne wczytywanie nie tylko żądanego modułu, a także wszystkie jego drzewo zależności. Przeglądarki nie muszą tego robić ale mogą to robić.

Jakie rozwiązanie do wstępnego wczytywania modułu i jego drzewo zależności, ponieważ do uruchomienia aplikacji potrzebne jest pełne drzewo zależności?

Przeglądarki, które decydują się na rekurencyjne wczytywanie zależności, powinny mieć skuteczną metodę deduplikacji więc najlepiej jest zadeklarować moduł i płaską listę jego zależności i ufać przeglądarce, że nie pobierze tego samego modułu dwa razy.

<head>
  <!-- dog.js imports dog-head.js, which in turn imports
       dog-head-mouth.js, which imports dog-head-mouth-tongue.js. -->
  <link rel="modulepreload" href="dog-head-mouth-tongue.mjs">
  <link rel="modulepreload" href="dog-head-mouth.mjs">
  <link rel="modulepreload" href="dog-head.mjs">
  <link rel="modulepreload" href="dog.mjs">
</head>

Czy wstępne ładowanie modułów poprawia wydajność?

Wstępne wczytywanie może pomóc w maksymalizacji wykorzystania przepustowości, ponieważ informuje przeglądarkę, co musi pobrać dane, aby nie utknęło bez żadnych działań podczas tych długich podróży w obie strony. Jeśli eksperymentujesz z modułami i natrafisz na problemy z wydajnością ze względu na drzewa zależności, może pomóc utworzenie płaskiej listy wczytań wstępnego.

Wciąż pracujemy nad wydajnością modułów, za pomocą Narzędzi dla programistów sprawdzisz, co dzieje się w Twojej aplikacji, rozważ podzielenie swojej aplikacji na kilka części. Znajdziesz tam mnóstwo pracujemy nad innymi modułami w Chrome, więc zbliżamy się do udostępnienia funkcji zasłużonego odpoczynku!