18 августа команда Next.js опубликовала подробный разбор Instant Navigations — набора возможностей, ради которого и затевался релиз 16.3 (вышел 3 августа). Вместе с текстом выложили четыре открытых демо-приложения, которые можно склонировать и посмотреть, как оно работает на реальном коде, а не на слайдах. Это важный момент для всех, кто держит сайт или сервис на Next.js: фреймворк наконец закрывает свою главную репутационную проблему — «серверный рендеринг быстрый, но переходы по ссылкам ощущаются вязко».
Что вообще чинили
Серверные компоненты (Server Components) дали фреймворку то, ради чего их делали: меньше JavaScript в браузере, нет цепочек запросов «страница ждёт запрос, который ждёт другой запрос». Но у этого была цена. Клик по ссылке уходил на сервер, и до ответа пользователь смотрел в пустоту. Классическое одностраничное приложение (SPA, single-page application) в этот момент уже рисует скелет интерфейса, потому что вся разметка у него в браузере.
Обойти это было можно — через отдельные файлы loading.tsx для каждого маршрута. Но правило «не забудь ни одного» плохо переживает год работы команды: один пропущенный файл — и у вас снова блокирующий переход, о котором вы узнаёте от пользователей.
Instant Navigations решает это иначе. Фреймворк сам вытаскивает из любого маршрута «оболочку» (shell) — ту часть интерфейса, которую можно отрисовать заранее, — и заранее подгружает её в браузер. Клик происходит, оболочка уже на месте, динамика дотекает через <Suspense>.
Два флага, на которых всё держится
Механизм опциональный и включается двумя строками в next.config.ts:
const nextConfig = {
cacheComponents: true,
partialPrefetching: true,
};
Cache Components — это развитие директивы 'use cache', появившейся в Next.js 16 в ноябре. Раньше она кешировала только на сервере; в 16.3 кеш впервые доехал и до клиента. Помеченная функция кешируется по своим аргументам, срок жизни задаётся через cacheLife, а инвалидация — через теги: cacheTag('drop-123') при чтении и updateTag('drop-123') из Server Action после записи. Повторный заход на страницу не показывает скелет вообще — данные уже есть.
Partial Prefetching отвечает за то, сколько именно контента ссылка тянет заранее. По умолчанию видимый <Link> подгружает одну оболочку на маршрут, общую для всех ссылок на него. Если нужно, чтобы конкретная ссылка приехала уже с данными под свой URL, ставится prefetch={true} — тогда в предзагрузку попадают и params, и searchParams, и привязанные к ним 'use cache'-чтения. Это ровно тот случай, когда карточка товара открывается с названием и ценой на месте, а не с тремя серыми полосками.
Раньше выбор был бинарный: либо общий loading.tsx, либо агрессивная полная предзагрузка. Теперь между ними появилась ручка регулировки. Команда прямо говорит, что это поведение станет стандартным в будущей мажорной версии, — включать флаги сейчас имеет смысл и как подготовку к миграции.
Четыре демо, которые можно потрогать
Августовский разбор построен вокруг четырёх приложений с открытым кодом на 16.3, и это самая практичная его часть:
- Next Beats — музыкальный плеер: библиотека, плейлисты, избранное, воспроизведение не прерывается при переходах между страницами.
- Drop — соцсеть для разработчиков: посты, подписки, профили, ленты по тегам и кешированные данные маршрутов.
- Flow — календарь с бронированием: события создаются и перетаскиваются на клиенте, недели кешируются и сбрасываются по тегу.
- Huddle — командный чат в духе Slack: каналы, треды, реакции, непрочитанное. Есть два варианта — на TanStack Query и на SWR.
Разбор показывает не только «счастливый путь». Там же — как сочетать серверные компоненты с клиентскими провайдерами состояния, как вкладывать <Suspense> друг в друга, чтобы блоки не прыгали при загрузке (нижняя граница ждёт верхнюю — страница собирается сверху вниз), как показывать мгновенный отклик через useOptimistic и useTransition и откатываться при ошибке, и как анимировать переходы через React-компонент <ViewTransition>.
Что достаётся всем, кто просто обновится
Главное: перечисленное ниже не требует ни флагов, ни правок в коде.
- Память в дев-режиме — до 90% меньше. Turbopack получил дисковый кеш и вытеснение из памяти по умолчанию. На дашборде Vercel цифра упала с 21,5 ГБ до 2 ГБ после компиляции 50 маршрутов, на сайте nextjs.org — с 4600 МБ до 840 МБ.
- Сборки быстрее. Дисковый кеш заработал и для
next build. Разброс большой: nextjs.org — примерно в 2,3 раза, часть проектов Vercel — в 5,5 раза. - Проверка типов на TypeScript 7. Достаточно поднять локальную зависимость до
typescript@^7— нативный порт компилятора примерно вдесятеро быстрее на тайпчеке. - Серверный рендеринг +22% запросов под нагрузкой. В App Router веб-стримы заменили на нативные потоки Node.js, убрав конвертацию между ними.
- Меньше запросов на предзагрузку. Мелкие префетчи склеиваются в один; Vercel со своей стороны отчитался о снижении их числа на 45%.
- Root params. Параметры уровня корня — например
[lang]— теперь читаются из любого серверного компонента черезnext/root-params, без прокидывания пропсов через полдерева. Для мультиязычных сайтов это заметное упрощение. - Свои error boundary через
catchError. Раньше границы ошибок конфликтовали сnotFound()иredirect()и умели сбрасывать только клиентское состояние. Теперь в обработчик приходит функцияretry(), которая перезапрашивает содержимое границы — включая повторный рендер серверных компонентов. - Glob-импорты. Turbopack поддержал совместимый с Vite
import.meta.glob— удобно для блогов и документации на локальных markdown-файлах, с горячей перезагрузкой. - Документация для ИИ-агентов по версии.
next devпишет и поддерживает блокAGENTS.mdсо ссылками на документацию из локальных node_modules, совпадающую с версией проекта. Ранние Skills, которые существовали только ради доставки актуальных доков агенту, команда сворачивает.
Три инструмента, чтобы не откатиться назад
Отдельная и, пожалуй, самая недооценённая часть релиза — средства контроля. Мгновенный переход легко сломать: кто-то добавил чтение cookies() в общий хедер, и весь маршрут свалился в рендер по запросу.
Instant Insights — панель в DevTools, которая сама подсвечивает переходы, оказавшиеся не мгновенными, и к каждой находке даёт готовый промпт для кодового агента. Navigation Inspector позволяет поставить загрузку на паузу на стадии оболочки и увидеть глазами, что именно показывается пользователю (в дев-режиме предзагрузка отключена, и без такого инструмента это неочевидно). Хелпер instant() для Playwright закрывает вопрос в CI: тест утверждает, какой контент обязан быть виден сразу, и падает, если рефакторинг это сломал.
Подводные камни
Instant Navigations меняет модель кеширования, поэтому включать флаги на боевом проекте без прогона тестов — плохая идея. Для существующих приложений есть руководства по миграции на Cache Components и по внедрению Partial Prefetching, а также готовые Skills, которыми можно поручить работу кодовому агенту.
Независимый разбор релиза от разработчика Ростана Мигана описывает регрессию в 16.3.0: при установленном пакете sharp усиленная защита оптимизатора изображений глобально блокировала декодирование SVG — а именно оно нужно ImageResponse для генерации Open Graph-картинок. Ответ приходил нулевого размера, но не всегда: getSharp() ленивый и мемоизированный, блокировка срабатывала только на первом промахе кеша. Исправление добавили в канареечные сборки 16.3.1. Если вы генерируете OG-превью динамически, это стоит проверить у себя.
Из экспериментального: React Compiler на Rust внутри Turbopack (флаг turbopackRustReactCompiler) — на приложении v0 время до готовой страницы сократилось на 34% на холодной сборке и на 46% на тёплой, но выигрыш такой только если вы полностью ушли от Babel. И experimental.useOffline — при обрыве связи навигация, запрос или Server Action не падают, а ждут восстановления и повторяются; хук useOffline позволяет показать плашку «переподключаемся». Сама команда честно помечает офлайн-режим как не готовый к продакшену.
Кому это нужно прямо сейчас
Обновиться на 16.3 стоит практически всем — половина списка выше работает без единой правки в коде, а экономия памяти в дев-режиме на больших проектах меняет ощущение от работы буквально в первый день. Флаги cacheComponents и partialPrefetching — история другая: это осознанная миграция, но с понятной выгодой для интернет-магазинов, каталогов, админок и любых интерфейсов, где пользователь много кликает между страницами.
И ещё аргумент, который легко упустить: скорость отрисовки после клика — это не только про комфорт, но и про Core Web Vitals, поведенческие факторы и конверсию. Vercel отчиталась и по инфраструктуре: неизменяемые статические ассеты теперь переиспользуются между деплоями — 17% меньше запросов к CDN и на 24% меньше переданных байт.
О том, почему TypeScript 7 стал настолько быстрее, мы писали отдельно. А про новый график исправлений безопасности во фреймворке — в этом материале.
Частые вопросы
Для большей части улучшений — нет. Экономия памяти в дев-режиме, ускорение сборок, +22% запросов под нагрузкой в App Router и склейка мелких префетчей включены по умолчанию и работают сразу после npm install next@latest. Отдельно включать нужно только Instant Navigations — флаги cacheComponents и partialPrefetching в next.config.ts.
Cache Components отвечают за кеширование: директива 'use cache' теперь работает и на клиенте, поэтому повторный заход на страницу может обойтись без скелета и без запроса к серверу. Partial Prefetching отвечает за предзагрузку: он вытаскивает из маршрута готовую к показу оболочку и подтягивает её в браузер до клика, а с prefetch={true} — ещё и данные, зависящие от конкретного URL.
Флаги меняют модель кеширования, поэтому включать их стоит осознанно и с прогоном тестов. При этом команда Next.js заявила, что это поведение станет стандартным в будущей мажорной версии, — так что миграцию всё равно придётся делать, и лучше пройти её заранее на своих условиях. Для существующих приложений есть официальные руководства по миграции.
В независимом разборе релиза описана регрессия в версии 16.3.0: если в проекте установлен пакет sharp, усиленная защита оптимизатора изображений блокировала декодирование SVG глобально, а оно нужно ImageResponse для генерации динамических OG-превью. В результате ответ мог приходить нулевого размера, причём непостоянно. Исправление добавили в канареечные сборки 16.3.1.
Источники
- 1.Building App-like Experiences with Next.js 16.3 — Next.js Bloghttps://nextjs.org/blog/building-app-like-experiences-with-nextjs-16-3
- 2.Next.js 16.3 — официальный анонс релизаhttps://nextjs.org/blog/next-16-3
- 3.Next.js 16.3 support on Vercel — Vercel Bloghttps://vercel.com/blog/vercel-supports-next-js-16-3
- 4.Next.js 16.3 brings client-side caching to the App Router — Appwritehttps://appwrite.io/blog/post/nextjs-163-brings-client-side-caching-to-the-app-router
- 5.Next.js 16.3: the real wins, and a warning about OG images — Rostand Miganhttps://www.rostand.dev/blog/nextjs-16-3



