# Turbopack у Next.js 16.4: компілювати менше – нова форма оптимізації

> Що змінилося в Turbopack у Next.js 16.4: кеш на 20–25% менший, lazy server HMR, спільний runtime, коротші class names у production і Bundle Analyzer зі снапшотами й diff-ами. Розбираємо, що реально відчує великий проєкт.

- Автор: Юра Скиба (https://cookiesoftware.io)
- Опубліковано: 2026-10-15
- Категорія: React і Frontend
- Canonical: https://cookiesoftware.io/blog/turbopack-nextjs-16-4

---

Turbopack у Next.js 16.4 приніс набір змін, які об'єднує одна думка: не роби роботу раніше, ніж вона потрібна. Disk cache став на 20–25% меншим без жодної конфігурації, server HMR – лінивим (оновлюються лише роути, які реально запитуються), runtime тепер один спільний чанк на всі роути, production-бандли поменшали завдяки коротшим CSS-класам і export mangling, а Bundle Analyzer навчився снапшотів, diff-ів і виділення critical render path. Нічого революційного – і саме тому це хороший реліз: нудні оптимізації, які відчуваються щодня.

## Менший кеш без твоєї участі

Disk cache Turbopack тепер використовує на 20–25% менше місця. Механіка чесна: Zstandard-компресія для даних, які займають найбільше простору, LZ4 для метаданих (щоб lookup лишався швидким), плюс розумніша компакція, яка ефективніше викидає застарілі дані.

Чому це важливо не лише для диска: на CI з кешованими білдами розмір кеша – це час завантаження/вивантаження артефактів. Мінус чверть обсягу – це хвилини на місяць, які ніхто не помічає окремо, але всі відчувають сумарно.

Окремо в 16.4 з'явився experimental-прибиральник `turbopackGc` – garbage collector, який чистить невикористану скомпільовану роботу з пам'яті й кеша, включно зі слідами видалених роутів із минулих сесій. Якщо у тебе довгі dev-сесії на великому проєкті – варто спробувати.

## Lazy server HMR: не оновлюй те, на що ніхто не дивиться

Раніше зміна shared server-модуля могла тригерити оновлення роутів, які ти відкривав раніше в dev-сесії – навіть якщо зараз із ними не працюєш. У 16.4 Turbopack компілює і застосовує server-оновлення лише тоді, коли запит їх реально потребує. Сторінка, яку ти дивишся, оновлюється як завжди; решта чекає, поки їх знову запитають.

У pet-проєкті різницю можна не помітити. У великому застосунку з десятками роутів і monorepo зі спільними модулями – це відчутний developer experience: редагуєш `lib/utils.ts` і не платиш за перекомпіляцію половини застосунку.

Туди ж – experimental `turbopackLazyDynamicImports`: клієнтські `import()` компілюються лише коли браузер їх запитав, а не на старті dev-сервера. Бібліотека, що вантажиться по кліку, більше не сповільнює перший запуск.

## Production: спільний runtime і коротші імена

Дві зміни для production-бандлів:

- **Спільний runtime-чанк.** Runtime Turbopack тепер один на всі роути замість копій. Менший сумарний download і кращий cache hit rate між сторінками.
- **Коротші імена.** CSS Modules у production отримують короткі class names (dev лишає довгі – для дебага), а export mangling скорочує внутрішні імена експортів, які зшивають модулі.

Це класичні «безкоштовні» відсотки: нічого не треба міняти в коді, бандл просто меншає після апгрейда.

## Bundle Analyzer стає інструментом, а не картинкою

Найцікавіша для мене частина релізу. Analyzer тепер:

- показує **найбільші клієнтські роути** на окремій головній сторінці;
- має табличний вигляд із сортуванням за найбільшими contributors;
- **автоматично зберігає снапшоти** аналізів і вміє **diff-ити бандли** між змінами;
- **відрізняє модулі на critical render path** і дозволяє відфільтрувати async-залежності.

Останній пункт – головний. «Наш bundle 2 MB» – слабка метрика: туди входить і те, що вантажиться асинхронно після interaction, і те, що реально блокує перший рендер. Питання, яке варто ставити: **скільки байтів лежить на критичному шляху до першої взаємодії?** Це прямий місток до LCP/INP, які ми розбирали в [статті про Core Web Vitals](/blog/core-web-vitals-react).

Практичний workflow тепер виглядає так:

1. Зроби снапшот аналізу до зміни.
2. Внеси зміну (нова бібліотека, рефакторинг, новий роут).
3. Прожени аналіз ще раз і подивись diff.
4. Окремо перевір critical path: чи виросло те, що блокує рендер, чи лише async-хвіст.
5. Підтверди field-метриками у production – лабораторний аналіз без польових даних [бреше рівно настільки, наскільки йому зручно](/blog/core-web-vitals-react).

Бонус для тих, хто працює з агентами: поруч із analyzer-ом з'явився experimental agent skill `next-bundle-optimizer` (`npx skills add vercel/next.js --skill next-bundle-optimizer`) – агент сам проходить цикл «знайти → діагностувати → запропонувати зменшення». Це той самий патерн «пакуємо процес, а не промпт», який ми розбирали [на прикладі Claude Code](/blog/claude-code-dlia-react).

## Пастки bundle-оптимізації

- **Оптимізувати bundle без снапшота «до».** Без базової лінії ти не знаєш, чи допомогла зміна. Тепер снапшоти вбудовані – немає виправдань.
- **Дивитись на сумарний розмір замість critical path.** Перенесення коду в async-чанк не «зменшило bundle», воно перенесло вартість у інший момент. Іноді це правильно, але це інше рішення.
- **Вмикати всі experimental-прапорці одразу.** `turbopackGc`, lazy dynamic imports, worker threads – вмикай по одному і дивись на поведінку. Experimental означає experimental.
- **Міряти лише в dev.** Коротші class names і export mangling працюють у production; висновки про розмір роби з production-білда.

## Спробуй diff на своєму бандлі

Онови тестову гілку до 16.4 і зроби три речі: (1) зафіксуй розмір `.next/cache` до і після – побачиш свої 20–25%; (2) відкрий Bundle Analyzer, знайди найбільший клієнтський роут і подивись, що з нього лежить на critical path; (3) зроби снапшот, додай будь-яку «невинну» бібліотеку, яку давно хотів, і подивись diff. Третій крок зазвичай найповчальніший.

Хороша інженерна культура навколо бандла – це не разовий «тиждень оптимізації», а дешевий постійний цикл: снапшот, diff, рішення. У 16.4 цей цикл нарешті вбудований в інструмент. Як це поєднується з рештою моделі 16.4 – у [розборі Cache Components](/blog/nextjs-16-4-cache-components).
