Веб-розробка

Next.js 15: що змінилося насправді і як перевірити це на своєму проєкті

Turbopack, кешування fetch за замовчуванням, асинхронні params і те, що з цього справді доходить до відвідувача. Плюс чотири команди для перевірки власного проєкту.

Про Next.js 15 писали переважно в жанрі «революція». Далі — без цього. Розберемо, що саме змінилося в релізі, які зміни ламають робочий код мовчки, і як за пів години перевірити, чи ваш проєкт узагалі отримує з нової версії щось, крім номера в package.json.

Turbopack: швидше, але не там, де ви думаєте

Turbopack отримав стабільний статус для next dev — це зафіксовано в офіційних release notes Next.js. Замість повного перебудовування графа модулів після кожної правки він перезбирає тільки те, що змінилося, і тримає результат у пам'яті між збірками.

Наскільки швидше стане особисто у вас — залежить від кількості модулів, глибини імпортів, набору CSS-обробників і швидкості диска. Порівняльної таблиці «було / стало» тут не буде: цифри з чужого ноутбука на чужому проєкті нічого не кажуть про ваш. Заміряйте самі — time перед запуском dev-сервера, потім перемкніть прапорець і повторіть на тому самому коді.

І головне, про що зазвичай мовчать. Швидкість dev-сервера не має жодного стосунку до того, як швидко сайт відкриється у відвідувача. Turbopack працює на вашій машині під час розробки. Відвідувач бачить продакшн-збірку, віддану з сервера в іншій країні, через мобільну мережу, на телефоні п'ятирічної давності. Це два різні світи, і прискорення першого не покращує другий ні на мілісекунду.

Що справді впливає на швидкість у відвідувача

Між кліком і появою контенту людина не бачить нічого. Чим довша ця пауза, тим більша частка людей закриває вкладку — і ці люди не побачать ні товару, ні ціни, ні форми. Швидкість не продає. Вона визначає, скільком людям вашу пропозицію взагалі покажуть.

Технічно тут два важелі: TTFB (час до першого байта — кешування, запити до бази, налаштування сервера) і вага HTML, який браузер має завантажити до першого рендеру. Next.js допомагає з обома, але роботу за вас не робить.

Наші заміри на живих сайтах, зроблені зовнішньо через curl 31.07.2026:

  • корпоративний односторінковий сайт консалтингової компанії на Next.js — TTFB 254 мс, повний документ за 342,6 мс, HTML 102,1 КБ;
  • SaaS-платформа для рерайту описів товарів — TTFB 220,6 мс при 141 КБ HTML.

Це наш вимір, і це стан сервера, а не бізнес-показник клієнта. Чесна межа тут така: TTFB — тільки серверна частина. Повний час до інтерактивності в реального відвідувача залежить ще від його пристрою, мережі, ваги картинок і сторонніх скриптів, які підключили вже після нашого заміру. І ще важливіше: сайт, що відкривається за 200 мс, просто швидше покаже людині причину піти, якщо ціна вища за ринок або товару немає в наявності. Швидкість прибирає технічну втрату. Попиту вона не створює.

Кешування: fetch більше не кешується за замовчуванням

Найтихіша зміна релізу. У Next.js 14 результат fetch() за замовчуванням кешувався, у 15-й — ні. Те саме з GET-обробниками в Route Handlers і з клієнтським кешем роутера.

Ламається це без помилок. Код працює, тести проходять, а сервер починає ходити в API на кожен запит замість одного разу на хвилину. Помічають зазвичай по рахунку від хостингу або по TTFB, який виріс утричі після оновлення.

Що робити при міграції: пройтися по всіх fetch() у серверних компонентах і проставити намір явно.

// Раніше вистачало голого fetch — тепер намір треба озвучити
const products = await fetch('https://api.example.com/products', {
  next: { revalidate: 3600 }, // кешувати годину
})

// Жорсткий кеш, якщо дані статичні
const config = await fetch('https://api.example.com/config', {
  cache: 'force-cache',
})

Асинхронні params, searchParams, cookies і headers

Друга зміна, яку не можна пропустити: динамічні API стали асинхронними. params і searchParams у сторінках, а також cookies() і headers() тепер повертають проміс.

// Next.js 15
export default async function ProductPage({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params
  return <Product slug={slug} />
}

Офіційний codemod (npx @next/codemod@canary upgrade latest) перепише більшість викликів автоматично. Але не всі: звернення до params через проміжну змінну або деструктуризацію в іншому файлі він не бачить. Після прогону перевірте типи руками — саме тут ховаються помилки, які виявляться тільки в рантаймі на проді.

Server Actions і те, про що забувають

Синтаксис не змінився, змінилася зрілість підходу.

'use server'

import { revalidatePath } from 'next/cache'
import { auth } from '@/lib/auth'

export async function createPost(formData: FormData) {
  const session = await auth()
  if (!session?.user) throw new Error('Unauthorized')

  const title = formData.get('title') as string
  await db.post.create({ data: { title, authorId: session.user.id } })

  revalidatePath('/blog')
  return { success: true }
}

Зверніть увагу на перші два рядки тіла функції. Server Action — це публічний HTTP-ендпоінт зі згенерованим ідентифікатором. Те, що на фронтенді кнопка показується лише залогіненому користувачу, не заважає викликати дію напряму з консолі. Авторизація перевіряється всередині дії. Завжди, навіть коли здається очевидним, що сюди ніхто чужий не потрапить.

React 19: useOptimistic

Next.js 15 працює на React 19, і найкорисніше з нового для типового комерційного проєкту — оптимістичні оновлення без ручного керування станом.

function CommentForm({ comments }) {
  const [optimisticComments, addOptimistic] = useOptimistic(
    comments,
    (state, newComment) => [...state, { ...newComment, pending: true }]
  )

  async function formAction(formData: FormData) {
    const text = formData.get('comment') as string
    addOptimistic({ text })
    await submitComment(text)
  }

  return <form action={formAction}>{/* ... */}</form>
}

Коментар з'являється у списку миттєво, а при помилці сервера React сам відкочує стан до попереднього. Раніше під це писали окремий редюсер і руками тримали список «ще не збережених» елементів.

Що бачить пошуковий бот і AI-асистент

Тут у Next.js є перевага, яку легко втратити необережною архітектурою. Серверний рендеринг віддає готовий HTML одразу — і саме це потрібно агентам AI-асистентів, які здебільшого не виконують JavaScript. Якщо сайт зібраний як клієнтська оболонка, що добирає контент після завантаження, агент побачить порожню сторінку і процитує когось іншого.

З виміряного нами: у виробника негорючих стінових панелей на Next.js карта сайту містить 164 URL і жодного дубля, TTFB на головній 244 мс, а в розмітці — 8 типів JSON-LD, включно з Organization, PostalAddress і SearchAction (наш вимір 01.08.2026). У SaaS-платформи з прикладу вище в розмітці лежать FAQPage, SoftwareApplication і Offer.

Чесна межа: ніхто, включно з нами, не може обіцяти згадку у відповіді AI-асистента. У вендорів немає ні гарантій, ні прозорих правил відбору, а обсяг переходів з асистентів поки що малий порівняно зі звичайним пошуком. Це робота на випередження з невідомою віддачею, і подавати її інакше було б неправдою.

Окремо про карту сайту. App Router уміє генерувати її з коду через app/sitemap.ts, і це варто зробити відразу. Але Google у власній документації прямо пише, що карта допомагає знайти сторінки й не гарантує ні сканування, ні індексації. Кількість URL у карті ніколи не дорівнює кількості сторінок в індексі — реальну цифру видно тільки у вашій Search Console.

Перевірка свого проєкту за пів години

Чотири команди дадуть більше розуміння, ніж будь-яка стаття, включно з цією.

Перша відповідь сервера на проді:

curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s | всього: %{time_total}s | розмір: %{size_download} байт\n" https://ваш-сайт.com/

Що бачить бот, який не виконує JavaScript:

curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1)" https://ваш-сайт.com/ | wc -c

Якщо в цьому HTML немає назви товару чи заголовка h1, який видно в браузері, — контент збирається на клієнті, і для бота сторінка порожня:

curl -s https://ваш-сайт.com/product/example | grep -c "назва товару"

Чи живий sitemap:

curl -sI https://ваш-сайт.com/sitemap.xml | head -3

Останнє ламається частіше, ніж здається. У наших замірах регулярно трапляються два сценарії: robots.txt посилається на карту, яка віддає 404, або карта відповідає кодом 200 із тілом на нуль байт. Формально працює, фактично бот не отримує нічого — і жоден моніторинг доступності цього не покаже, бо статус-код правильний.

Коли мігрувати

Ситуація Що робити
Новий проєкт Стартувати одразу на 15-й
Активна розробка, реліз не завтра Планувати міграцію, починати з codemod на окремій гілці
Стабільний прод, змін мало Не поспішати; спершу перевірити сумісність залежностей із React 19
Багато сторонніх UI-бібліотек Перевірити React 19 до всього іншого — це найчастіша причина застрягти на пів дороги

Найбільший ризик міграції — не сам Next.js, а екосистема навколо нього. Оновлення фреймворку зазвичай проходить за день. Тиждень з'їдає бібліотека компонентів, яку автор ще не оновив під React 19, і вибір між форком, заміною та очікуванням.

Що з цього має значення

Turbopack робить приємнішою вашу роботу, і це чесна користь — просто вона не переходить у метрики сайту. Зміни в кешуванні й асинхронні API вимагають уваги при оновленні, інакше проєкт почне поводитись гірше без жодного повідомлення про помилку. А серверний рендеринг залишається тим, заради чого Next.js має сенс у комерційному проєкті: він віддає готовий HTML і людині, і боту, і агенту асистента.

Наскільки це вплине на ваші заявки й продажі — залежить від ніші, попиту й поточного стану сайту. Технічна частина прибирає втрати. Решту вирішує пропозиція.

Теги

Next.jsReactTypeScriptPerformance

Вам сподобалась стаття?

Ваша думка допомагає нам створювати кращий контент

Поділіться з друзями

Знайшли щось корисне?

Допоможіть іншим дізнатись про це — поділіться статтею в соціальних мережах

Дякуємо, що допомагаєте нам рости

Засновник LIONEX

Владислав Чистяков

Пише про те, що робить руками: інтернет-магазини на OpenCart, застосунки на Next.js, інтеграції та швидкість сайтів. У статтях — заміри й перевірки, які читач може повторити на своєму проєкті, а не загальні поради. Комерційна розробка з 2015 року.

Питання

Часті запитання

Відповіді на популярні питання по темі

Чи варто оновлюватись до Next.js 15, якщо на 14 усе працює?

Саме по собі оновлення не робить сайт швидшим для відвідувача — це зміна інструмента, а не результату. Вагома причина оновитись з'являється тоді, коли ви впираєтесь у щось конкретне: довгі збірки, потреба в нових можливостях React 19 або залежність, яка вже не підтримує стару версію. Якщо нічого з цього немає, спокійно лишайтесь на 14 і плануйте перехід на час, коли він нікому не заважатиме.

Turbopack прискорить мій сайт для відвідувачів?

Ні. Turbopack прискорює складання проєкту в розробника — холодний старт і перезавантаження після правки. На те, що бачить відвідувач, він не впливає взагалі: у браузер їде результат збірки, а не інструмент, яким її зробили. Швидкість сторінки вирішують інші речі — час відповіді сервера, вага зображень, кількість скриптів.

Що ламається при міграції найчастіше?

Дві речі. Перша — params, searchParams, cookies і headers стали асинхронними, і код, який читав їх напряму, тихо перестає працювати. Друга й підступніша — fetch більше не кешується за замовчуванням: сторінки, які раніше віддавались із кешу, починають ходити в базу на кожен запит. Сайт при цьому не падає, він просто стає повільнішим, і зв'язок з оновленням помічають не одразу.

Оновлення версії покращить позиції в пошуку?

Версія фреймворку не є фактором ранжування, і обіцяти тут нема чого. Опосередкований вплив можливий лише через наслідки: якщо після переходу сторінки стали віддаватись швидше, це видно в показниках швидкості, які Google справді враховує. Але той самий результат досягається й без міграції, і навпаки — невдале оновлення здатне швидкість погіршити.

Як перевірити свій проєкт, не наймаючи нікого?

За пів години й без сторонніх сервісів: подивитись, чи не читаються params синхронно, перевірити, які запити ходять у базу на кожен рендер, і порівняти час відповіді сторінки до й після. У статті це розписано покроково. Якщо після перевірки лишились сумніви — напишіть, подивимось разом; розбір задачі безкоштовний.

Отримуйте найкращі статті на пошту

Підпишіться на нашу розсилку та отримуйте корисні поради, інсайти та новини про веб-розробку, маркетинг та бізнес.

Ми поважаємо вашу приватність. Відписатись можна в будь-який момент.

Далі в блозі

Схожі статті

154 помилки типів, які викидала збірка: що в них знайшлосьВеб-розробка

154 помилки типів, які викидала збірка: що в них знайшлось

21 вересня 2026 року перевірка типів на нашому сайті показала 154 помилки, хоча збірка щоразу була зеленою: результат перевірки просто викидався. Усередині знайшлись нулі в статистиці посилань і в експорті аналітики, сортування, що не сортувало, і тести, які не запускались. Розповідаємо, як розбирали, що змінили і як перевірити свій проєкт.

Читати далі
Сертифікати продовжуються самі: TLS на 116 сайтах і один, що не продовживсяВеб-розробка

Сертифікати продовжуються самі: TLS на 116 сайтах і один, що не продовжився

22 вересня 2026 року ми перевірили HTTPS-сертифікати на 116 сайтах, які вже міряли для ринкових вимірів, і для 104 з них порівняли стан із серпневим. Усі 116 пройшли перевірку, 108 стоять на 89- і 90-денних безкоштовних сертифікатах, і лише в одного сайту сертифікат досі не продовжився, хоча за типових налаштувань уже мав би. Розбираємо заміри, межі методу й показуємо, як перевірити свій сайт однією командою.

Читати далі
Healthcheck дав 60 % запитів застосунку: що побачили в першу добу метрикВеб-розробка

Healthcheck дав 60 % запитів застосунку: що побачили в першу добу метрик

21 вересня 2026 року, у першу добу обліку запитів за маршрутами, службовий /api/health отримав 13 666 запитів — 60 % трафіку застосунку, і кожен ішов у спільну базу. Розповідаємо, які два налаштування це прибрали, яку ціну маємо за них і як перевірити свій healthcheck.

Читати далі