awesome-everything EN
↑ Обратно к восхождению

Архитектура фронтенда

Code splitting: чтение кода

Суть Читай реальные React/JS-сниппеты разбивки — границу dynamic import, раскладку lazy+Suspense и обработчик prefetch-on-hover — и выбирай поведение или самый высокорычажный фикс.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 13 min

Баги разбивки живут в том, где стоит граница и когда запрашивается чанк. Читай каждый сниппет, прослеживай тайминг запросов, который браузер реально выполняет, и выбирай фикс, который senior сделает первым.

Цель

Потренируй чтение точек разбивки так, как ты их дебажишь в проде: найди, где реально стоит граница dynamic import, увидь, когда Suspense триггерит загрузку, и заметь waterfall, который упредил бы hint.

Сниппет 1 — где стоит граница

// A: импорт на верхнем уровне модуля — бандлится в родительский чанк
import { HeavyEditor } from "./HeavyEditor";

function EditPanel({ open }) {
  if (!open) return null;
  return <HeavyEditor />;
}

// B: dynamic import внутри гейта
const HeavyEditor = React.lazy(() => import("./HeavyEditor"));

function EditPanel({ open }) {
  if (!open) return null;
  return (
    <Suspense fallback={<Spinner />}>
      <HeavyEditor />
    </Suspense>
  );
}
Викторина

Редактор весит 200 KB и открывается только по клику на Edit. Что реально отгружает каждая версия и какая здесь правильная?

Сниппет 2 — вложенные границы Suspense

const Dashboard = React.lazy(() => import("./Dashboard"));
const Chart = React.lazy(() => import("./Chart"));

function Page() {
  return (
    <Suspense fallback={<PageSkeleton />}>
      <Dashboard>
        <Suspense fallback={<ChartSpinner />}>
          <Chart />
        </Suspense>
      </Dashboard>
    </Suspense>
  );
}
Викторина

На телефоне с RTT 150 ms в каком порядке загружаются чанки Dashboard и Chart и почему это важно?

Сниппет 3 — prefetch по hover

const Settings = React.lazy(() => import("./Settings"));

function NavLink() {
  return (
    <a
      href="/settings"
      onMouseEnter={() => import("./Settings")}
    >
      Settings
    </a>
  );
}
Викторина

Что делает обработчик onMouseEnter и какой failure mode, если его убрать?

Итог

Три вещи решают поведение разбивки в коде: статический верхнеуровневый импорт всегда бандлится в родительский чанк, поэтому только import() создаёт точку разбивки — и runtime-условие этого не меняет. Вложенные границы React.lazy обнаруживаются последовательно, поэтому каждый уровень добавляет round trip на канале с высоким RTT. А запуск import() заранее (на hover или idle) прогревает кэш чанка, чтобы итоговое монтирование пропустило waterfall и спиннер. Читай, где стоит граница и когда триггерится загрузка, затем сдвигай триггер раньше, а не сливай чанк обратно.

Продолжить восхождение ↑Code splitting: почини waterfall
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.