Суть Читай реальный конфиг бандлера, паттерны import, сниппет size-limit в CI и заголовок Priority, предсказывай эффект на поставляемые байты и выбирай фикс с наибольшим рычагом.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min
Проблемы bundle диагностируются в конфигах, строках import, treemap анализатора и логе CI. Читай каждый сниппет как сеньор, затем выбирай фикс, который реально двигает поставляемые байты — а не тот, что двигает только провод.
Цель
Отработай цикл, который ты гоняешь на каждом bundle-ревью: читай import или конфиг, предсказывай, тащит ли он мёртвый вес, и берись за фикс с наибольшим рычагом — режь или shake байты раньше, чем тянуться к compression или к ручке.
Сниппет 1 — barrel re-export
// components/index.tsexport * from './Button';export * from './Modal';export * from './RichTextEditor'; // тянет 180 KB editor-либу// потребительimport { Button } from '@/components'; // здесь используется только Button
Викторина
Completed
Роут использует только Button, но анализатор показывает 180 KB editor в этом чанке. Что происходит и каков фикс?
Heads-up Button не импортирует editor. Именно `export *` в barrel тащит editor в граф для любого потребителя barrel.
Heads-up Barrel с `export *` часто побеждает tree-shaking: бандлер держит реэкспортированные модули, когда потреблён даже один экспорт barrel. Editor поставляется.
Heads-up sideEffects: false помогает с side effects на уровне модуля, а не с barrel, статически реэкспортирующим соседей используемого модуля. Чини реэкспорт.
Сниппет 2 — dynamic import
// грузит chart-панель, которой нет на первой отрисовкеfunction openPanel(name) { return import(`./panels/${name}`); // переменная в специфайере}// в другом месте — настоящий lazy-boundaryconst Editor = React.lazy(() => import('./Editor'));
Викторина
Completed
Обе строки выглядят как code-splitting. Какая реально даёт чистый, по отдельности shakeable чанк и почему?
Heads-up Переменный специфайер делает цель неизвестной на этапе сборки, поэтому бандлер должен включить всю совпавшую директорию в один чанк. Чисто сплитит только строковый литерал.
Heads-up Гибкость здесь и есть цена: переменная форма пакует всю папку ./panels. Строковый литерал `import('./Editor')` — тот, что даёт точный чанк.
Heads-up React.lazy построен на dynamic import() и ровно так ты и сплитишь компонент. Чистый — импорт со строковым литералом.
PR триггерит этот вывод. Автор просит смержить и 'починить в следующем спринте'. Какова верная сеньорская реакция?
Heads-up Каждый именованный лимит независим; homepage-лимит провален. Проходящий агрегат не оправдывает регрессию по конкретному роуту.
Heads-up Самостоятельное одобрение raise в провинившемся PR убивает gate. Raise требует протокола budget-raise: документированное обоснование и sign-off от perf-лида.
Heads-up Обход gate уничтожает его ценность — бюджеты эродируют по одному обходу за раз. Смысл в том, что каждое изменение видимо и явно.
Сниппет 4 — HTTP/3 priority
# Запрос браузера на критический app-чанкGET /_next/static/app.abc123.jsPriority: u=1# Запрос браузера на большой отложенный vendor-чанкGET /_next/static/vendor.def456.jsPriority: u=5# Конфиг CDN (misconfigured): игнорит клиентский Priority, отдаёт FIFO
Викторина
Completed
Приложение корректно code-split, и браузер шлёт вменяемые приоритеты RFC 9218, но CDN их игнорит и отдаёт first-come-first-served. Каков вероятный эффект и где это проверить?
Heads-up Транспортный выигрыш HTTP/3 не помогает, если подсказки приоритета игнорятся: пропускная способность делится поровну и критический чанк теряет фору.
Heads-up Без учтённых приоритетов порядок недетерминирован / FIFO — размер не толкает его в конец. Именно корректные приоритеты поставили бы малый критический чанк первым.
Heads-up Un-split возвращает полную стоимость parse на критический путь. Фикс — заставить CDN учитывать приоритеты, а не отказываться от splitting.
Итог
Каждая регрессия bundle читается в конфиге и выводе: barrel с export * и dynamic import с переменным специфайером тихо побеждают splitting и tree-shaking; провал size-limit — это жёсткий gate, а не предложение отложить; и даже идеально сплитнутый bundle недодаёт, если CDN игнорит приоритеты HTTP/3. Диагностируй по анализатору и логу CI, чини убирая байты с критического пути первым делом, затем подтверждай порядок доставки — перемеряй, а не предполагай.