← Все статьи

Как Turbopack режет JavaScript на фрагменты в Next.js

Компромисс «один бандл vs сотни запросов», группы фрагментов и экспериментальные опции Next.js 16.3: умная загрузка, аналитика маршрутов, удаление мёртвого кода в CJS.

Как Turbopack режет JavaScript на фрагменты в Next.js
Содержание

Коротко

Turbopack в Next.js собирает клиентский JavaScript не в один файл, а во множество фрагментов бандла: свой код, зависимости и среда выполнения. В блоге Next.js разбирают, почему «всё в одном файле» и «файл на каждый модуль» одинаково плохи на длинной дистанции — и как слияние фрагментов внутри группы балансирует размер загрузки и число сетевых запросов. В Next.js 16.3 появились экспериментальные рычаги: умный выбор уже загруженных кусков, настройка под реальные маршруты, удаление неиспользуемого кода в модулях CommonJS и общий фрагмент среды выполнения.

Что произошло

Крайности простые. Один огромный файл хорошо кэшируется, но тянет код всех страниц даже на «лёгкий» маршрут. По файлу на страницу — без лишнего кода, зато общий <Footer /> скачивается снова и снова. По файлу на модуль — ничего лишнего и отличный кэш, зато сотни мелких запросов: накладные расходы HTTP и хуже сжатие, чем у крупных файлов.

Turbopack объединяет мелкие фрагменты в более крупные, но только внутри группы фрагментов — набора, который всегда грузится вместе (например, всё для /home или /blog). Так нельзя «донагрузить» на страницу код, который ей не нужен: внутри группы он и так уже в плане загрузки. Решение «сливать или нет» взвешивает сценарии: человек открыл одну страницу и ушёл, или ушёл дальше по сайту. Слияние общего и узкого модуля выгодно при одном заходе; при переходе на страницу, где нужен только общий кусок, браузер может скачать общее повторно — потому что оно уже «склеено» с ненужным.

На сайте nextjs.org сравнили три режима: без слияния, настройки по умолчанию и «всё в группе в один файл». Умолчания срезали число запросов больше чем вдвое при чуть меньшем объёме кода; максимальное слияние дало ещё меньше запросов, но примерно на 10% больше скачанного JavaScript на длинной сессии.

Почему это важно

Разбиение на фрагменты — не «настройка сборщика ради красоты», а прямой компромисс между первым экраном, кэшем и мягкой навигацией. Сборка решает слияние до визита и не знает, что уже лежит в кэше браузера; алгоритм ещё и угадывает долю одностраничных сессий (в статье — порядка двух третей). Отсюда разрыв между «быстрым первым заходом» и «дешёвыми последующими переходами».

Для команды на Next.js это объясняет, почему «просто уменьшите число фрагментов» или «дробьте всё мельче» без учёта маршрутов часто ухудшают картину. Новые флаги в 16.3 как раз закрывают слепые зоны: среда выполнения может выбрать дешевле — смерженный файл или недостающие куски; конфиг может подсказать реальные кластеры страниц вместо универсальной догадки.

На практике

  1. Обновитесь до Next.js 16.3+ и читайте опции под experimental.turbopackChunking в next.config.js, а не копируйте чужие «магические» числа.
  2. Включите generateComponentChunks: рядом со смерженными фрагментами эмитятся несмерженные; при запросе выбирается более дешёвый вариант с учётом уже загруженного.
  3. Подставьте свою аналитику: firstPageLoadPriority (по умолчанию 0.67), priorityRoutes для важных URL, clusters — группы маршрутов, которые ходят вместе.
  4. Для меньшего объёма клиента: experimental.turbopackCjsTreeShaking (удаление неиспользуемого кода в CommonJS; раньше стабильно работал в основном ESM) и experimental.turbopackSharedRuntime — один общий фрагмент среды выполнения вместо отдельного на каждую страницу (порядка 10 КБ и один блокирующий запрос на последующих переходах).
  5. Меряйте на своих сценариях навигации: на маркетинговом сайте с высоким «отскоком» выгоднее иное слияние, чем в кабинете с длинными сессиями.

Итог

Хорошее разбиение JavaScript — это не максимум и не минимум файлов, а осознанный компромисс внутри групп фрагментов плюс данные о том, как люди реально ходят по приложению. Экспериментальные опции Turbopack в Next.js 16.3 дают шанс приблизить сборку к кэшу браузера и к вашей карте маршрутов — имеет смысл включать их осознанно и проверять замерами, а не «вслепую на всё».