Pobierz CV
Projekty

Next.js 16.3 w praktyce – Instant Navigations, wydajność i AI

·Łukasz Kopyszko
[Next.js i web development][Next.js][Performance][AI][Turbopack]

Next.js 16.3 (stable, 3 sierpnia 2026) nie jest „kolejnym minorem z changelogu”. Daje dwie rzeczy, które czuć w codziennej pracy: nawigacje zbliżone do SPA bez porzucania Server Components oraz tooling, które nie zżera 16 GB RAM-u, gdy obok działa agent. Pytanie nie brzmi „co doszło do configu”, tylko: co z tego ma użytkownik aplikacji i co ma developer, który tę aplikację utrzymuje.

Poniżej na podstawie oficjalnego bloga Next.js — bez przepisywania release notes.

Co się zmieniło w 16.3

Dwie warstwy. Pierwsza działa po npm install next@latest bez ruszania kodu: mniej RAM w next dev (nawet do ~90% w długich sesjach, eviction + disk cache Turbopack), szybsze powtórne builde’y, natywne streamy Node w SSR (do ~22% więcej requestów pod obciążeniem), składanie małych prefetchy, TypeScript 7 jako opcja w next build.

Druga warstwa jest opt-in i to ona nazywa się Instant Navigations:

const nextConfig = {
  cacheComponents: true,
  partialPrefetching: true,
};

Te flagi mają stać się defaultem w przyszłym majorze. Dziś to świadoma migracja, nie „włącz i zapomnij”.

Instant Navigations — co czuje użytkownik

Server Components zmniejszyły JS i waterfall, ale klik w link często czekał na serwer. SPA pokazywało skeleton od razu. 16.3 wyciąga z trasy „shell” (statyczne + cache’owane, niezależne od URL) i podaje go przeglądarce zanim ktoś kliknie.

Efekt: pierwsza klatka po kliknięciu jest lokalna. Reszta (cena, stock, personalizacja) dopływa. To nie magia — to prefetch shellu + Suspense / 'use cache'. Jeśli trasa nie ma czego pokazać natychmiast, DevTools (Instant Insights) to zgłosi, zamiast udawać, że „u nas jest szybko”.

Partial Prefetching

Wcześniej: albo loading.tsx, albo agresywny pełny prefetch. Albo za mało, albo za drogo.

Z Partial Prefetching Next buduje jeden App Shell na trasę i reuse’uje go dla wszystkich linków do tej trasy. Domyślnie link nie ciągnie treści zależnej od params. Gdy produkt ma być „pełny” przed kliknięciem:

<Link href={`/produkty/${slug}`} prefetch={true}>
  {title}
</Link>

prefetch={true} przy włączonym Partial Prefetching wchodzi w runtime prefetch: resolvuje params/searchParams. Nie wklejaj tego na każdy kafelek w siatce 200 produktów — zjesz budżet sieci. Shell na listing, pełny prefetch na „ostatnio oglądane” albo CTA.

Migracja: włącz flagę, potem audyt starych prefetch. Oficjalny skill next-partial-prefetching-adoption jest od tego, nie od zgadywania.

Server Components, streaming, cache

Model się nie odwraca: RSC + Suspense zostają klockami. Zmienia się jawność cache. 'use cache' (z linii 16) spina się z client cache i prefetchingiem. ISR przy Cache Components: URL-e poza generateStaticParams mogą pokazać shell pierwszemu odwiedzającemu, a w tle dociągnąć prerender. Kolejny request bierze gotowe.

Dla headless WordPress to konkret: lista 5 tys. wpisów nie musi być w buildzie. Pierwszy hit nie musi też wisieć na TTFB. Więcej w Next.js + headless WordPress i w przewodniku po headless.

Developer experience i pamięć

Długi next dev obok Cursora, tsc i przeglądarki to był konkurs, kto pierwszy zje RAM. 16.3: disk cache (z 16.1) + eviction — cache nie trzyma w pamięci każdej odwiedzonej trasy w nieskończoność. To nie mikrooptymalizacja. To warunek, żeby agent i aplikacja działały na tym samym laptopie.

Do tego: Navigation Inspector (pauza na shellu w dev, gdzie prefetch i tak jest wyłączony), catchError zamiast error boundary, które gryzło się z notFound()/redirect(), import.meta.glob w Turbopack, next/root-params zamiast prop-drillingu [lang].

import { lang } from "next/root-params";

export default async function Page(props: PageProps<"/[lang]/blog/[slug]">) {
  const { slug } = await props.params;
  const language = await lang();
  return <Article slug={slug} lang={language} />;
}

Turbopack

FileSystem Cache działa też na next build (domyślnie). Vercel raportuje nawet 5.5× na powtórnych CI. Experimental: Rustowy React Compiler wewnątrz Turbopack (turbopackRustReactCompiler), bez Babelowego round-trip. Ma sens, gdy naprawdę zszedłeś z Babela.

Narzędzia pod coding agents

16.3 traktuje agenta jak obywatela, nie jako „ktoś odpali ChatGPT”.

  • AGENTS.mdnext dev dopisuje zarządzany blok z wersjonowanymi docs z node_modules/next. Agent czyta API tej wersji, nie halucynacje z 14.x. Twój własny tekst poza blokiem zostaje.
  • Skills — knowledge skille „jak działa App Router” są wycofywane (docs są w paczce). Zostają workflow: next-dev-loop, adopcja Cache Components / Partial Prefetching.
  • MCP/_next/mcp + next-devtools-mcp: get_compilation_issues, compile_route z działającego dev serwera, bez pełnego next build po każdej edycji.

Jak tego używać w zespole — osobno: Cursor i AI w workflow. 16.3 daje hooki; nie zastępuje review.

Kiedy upgrade ma sens

  • Od razu, jeśli bolą Cię RAM w dev, czas CI albo prefetch spam. Benefity „dla każdego appa” nie wymagają Cache Components.
  • Instant Navigations, gdy masz dużo client nawigacji (dashboard, listing → detal) i mierzysz TTFB po kliknięciu, nie tylko Lighthouse na pierwszym URL.
  • Później, gdy żyjesz na custom cache / middleware, które zakłada stare prefetch. Wtedy plan migracji, nie piątkowy bump.

Pułapki migracji

Layout, który czyta cookies() albo headers(), wyłącza prerender shellu dla całej gałęzi. Objaw: Instant Insights krzyczy, a użytkownik po kliknięciu czeka na TTFB jak w 2024. Naprawa: zsuń odczyt cookies do małego Client Component albo za Suspense, nie do app/layout.tsx.

// e2e/instant-navigation.spec.ts
import { expect, test } from "@playwright/test";
import { instant } from "@next/playwright";

test("listing shell is instant", async ({ page }) => {
  await page.goto("/projekty");
  await instant(page, async () => {
    await page.click("a[href*="/projekty/"]");
    await expect(page.locator("h1")).toBeVisible();
  });
});

ISR z Cache Components: generateStaticParams prerenderuje subset. Reszta URL-i dostaje shell przy pierwszym hicie, potem pełny snapshot. Nie musisz mieć 5 tys. slugów w buildzie — musisz mieć webhook, który po publikacji w CMS zrobi revalidateTag.

  • cacheComponents + partialPrefetching zmieniają semantykę prefetch. Audyt linków.
  • Komponent czytający cookies() w layoucie zabija „instant” — Playwright helper instant() z @next/playwright ma to łapać w CI.
  • TypeScript 7 to osobny bump; 16.3 go nie wymaga.
  • Experimental useOffline / Rust compiler — nie na pierwszy deploy produkcyjny.

Po upgrade warto też spojrzeć na hosting: Next.js na VPS, jeśli nie siedzisz wyłącznie na Vercel. Przykłady ze stackiem Next w portfolio: Księgowy AI.

FAQ

Czy muszę włączać Instant Navigations?

Nie. 16.3 bez flag i tak jest lżejszy w dev i SSR. Instant to osobna umowa z cache’em.

Czy to zastępuje loading.tsx?

Nie kasuje pliku. Shell może wyjść z Suspense / 'use cache' bez osobnego pliku na każdą trasę. loading.tsx nadal jest legalny.

Czy agent „sam” zmigruje appkę?

Może przejść checklistę skilla. Nie podpisze rollbacku ani nie zrozumie, czemu header czyta cookies. To Twoja robota.

Podsumowanie

16.3 użytkownikowi daje klik, który nie czeka na serwer, jeśli dasz mu shell. Developerowi — mniej RAM, szybsze CI, docs w AGENTS.md i MCP zamiast wróżenia z builda. Flagi Instant włączasz, gdy rozumiesz prefetch i cache, nie dlatego, że ładnie brzmią na Twitterze.