IlmHamroh
JavaScript Full-stack/23-qism. Next.js14/43-dars16 daqiqa
Mundarija (26)

Next.js rendering strategiyalari: statik, dinamik va streaming (SSG, SSR, ISR, PPR)

Qisqacha: Next.js har sahifani yo build vaqtida (statik, ○), yo har so'rovda (dinamik, ƒ) chizadi — yoki ikkalasini aralashtiradi: statik qobiq oldindan tayyor, so'rovga bog'liq teshik esa oqim bilan keladi (qisman prerender, ◐). Siz strategiyani nom bilan tanlamaysiz: sahifa nimani ishlatsa, shunisi bo'ladi. cookies(), headers(), searchParams, connection() — "so'rov ma'lumoti", ular sahifani (yoki uning bir qismini) dinamik qiladi. Next 16 + Cache Components'da bunday ma'lumot <Suspense> dan tashqarida bo'lsa — build to'xtaydi va sizdan aniq qaror so'raydi.

Bu darsda

  • SSG, SSR, ISR, CSR atamalarini Next 16 belgilari (○, ◐, ƒ) bilan bog'laysiz.
  • Qaysi API sahifani dinamik qilishini bilasiz va buni build jadvalida ko'rasiz.
  • Uch strategiyaning narxini o'lchangan TTFB va sarlavhalar bilan solishtirasiz.
  • [stream], [cache], [block] tanlovlarini o'qiy olasiz.
  • portfolio ning har sahifasi uchun strategiya rejasini tuzasiz.

Oldin bilishingiz kerak: Hydration, Server Components, Next.js nima, Fayl-asosli routing.

1. Nega bu kerak?

Next.js nima darsining 3-mashqida chooseRendering(page) funksiyasini yozgandingiz: shaxsiy sahifa — CSR, har so'rovda yangi — SSR, qolgani — SSG. O'shanda aytgandik: haqiqiy Next.js'da bu qarorni funksiya emas, sahifa kodi hal qiladi.

Endi portfolio da shunday holat paydo bo'ladi. «Men haqimda» sahifasiga GitHub profilini (ochiq repolar soni, so'nggi loyihalar) qo'shmoqchimiz. Profil o'zgarib turadi — build vaqtida bir marta olib qo'yish yetmaydi. Lekin sahifaning qolgan qismi (matn, bilimlar, reja) — statik. Butun sahifani har so'rovda chizish isrof, butunlay statik qoldirish — eskirgan raqamlar.

Bu dars — qaror xaritasi. Qaysi kod sahifani qanday qiladi, va har tanlov qancha turadi. Keyingi ikki dars (Serverda ma'lumot olish, Streaming) shu xarita ustida GitHub blokini quradi.

Hayotiy o'xshatish: oshxonadagi uch xil taom. Non — ertalab pishirib qo'yiladi, kun bo'yi tayyor (statik). Shashlik — buyurtma kelganda pishiriladi (dinamik). Osh — qozon tayyor, lekin har likopchaga ustidan issiq go'sht qo'yiladi (qisman: tayyor asos + buyurtmaga xos qism).

2. To'rt atama va Next 16 belgilari

2.1 Klassik nomlar

Internetda va intervyularda bu nomlar ko'p uchraydi — Next.js nima darsida birinchi marta ko'rgansiz:

Atama To'liq nomi Qachon chiziladi
SSG Static Site Generation Build vaqtida, bir marta
SSR Server-Side Rendering Har so'rovda, serverda
ISR Incremental Static Regeneration Statik, lekin vaqti-vaqti bilan yangilanadi
CSR Client-Side Rendering Brauzerda, JS bilan

Next.js'ning eski versiyalari (Pages Router) har biri uchun alohida funksiya talab qilardi (getStaticProps, getServerSideProps — Pages Router merosi). App Router'da bunday funksiyalar yo'q: strategiya kodning o'zidan kelib chiqadi.

2.2 Build jadvalidagi belgilar

Next 16.4 build jadvali uchta belgi ishlatadi. Biz uchta tajriba sahifasi yozdik va bitta build'da ko'rdik:

text
├ ƒ /bloklovchi
├ ◐ /qisman
└ ○ /statik
Belgi Nomi (Next) Klassik atama
○ Static — prerendered as static content SSG (va cacheLife bilan — ISR)
◐ Partial Prerender — static HTML with dynamic server-streamed content SSG qobiq + SSR teshik (PPR)
ƒ Dynamic — server-rendered on demand SSR

CSR uchun belgi yo'q — u sahifa emas, komponent darajasidagi tanlov: client komponent brauzerda ma'lumot olsa (TanStack Query bilan Next.js), sahifaning o'zi baribir ○ bo'lishi mumkin.

PPR (Partial Prerendering, qisman oldindan chizish) — Next 16 + Cache Components'ning asosiy g'oyasi: bitta sahifada statik va dinamik qism yonma-yon. Fayl-asosli routing darsidagi ◐ /loyihalar/[slug] — shuning birinchi namunasi edi.

2.3 Tajriba sahifalari

Uch sahifa — uch strategiya:

tsx
// statik/page.tsx — so'rov ma'lumoti yo'q → ○
export default function Statik() {
  return <main><h1>Statik</h1><p>Build vaqtida chizildi.</p></main>;
}

// qisman/page.tsx — headers() Suspense ichida → ◐
async function Brauzer() {
  const ua = (await headers()).get("user-agent") ?? "";
  return <p>Brauzer: {ua.slice(0, 10)}</p>;
}
export default function Qisman() {
  return (
    <main>
      <h1>Qisman</h1>
      <Suspense fallback={<p>Aniqlanmoqda…</p>}>
        <Brauzer />
      </Suspense>
    </main>
  );
}

// bloklovchi/page.tsx — headers() tepada + instant = false → ƒ
export const instant = false;
export default async function Bloklovchi() {
  const ua = (await headers()).get("user-agent") ?? "";
  return <main><h1>Bloklovchi</h1><p>{ua.slice(0, 10)}</p></main>;
}

Telefonga sig'ishi uchun importlar va bir nechta qator qisqartirildi. headers() — next/headers dan: so'rov sarlavhalari (bu yerda brauzer nomi). U so'rovsiz ma'lum emas — shuning uchun "dinamik" (Request API'lar darsida chuqur).

2.4 Bir sahifa — bir nechta belgi

portfolio build jadvalida bitta papka uchun bir nechta qator bor edi:

text
└   /loyihalar/[slug]
  ├ ◐ /loyihalar/[slug]
  ├ ○ /loyihalar/vazifalar
  ├ ○ /loyihalar/bahor
  └ ○ /loyihalar/landing

Bu ham strategiyalar aralashmasi, faqat manzil bo'yicha. generateStaticParams uchta slug'ni oldindan aytdi — ular uchun tayyor HTML (○). Qolgan har qanday slug uchun Next.js ◐ qobiq saqlaydi: so'rov kelganda params haqiqiy qiymat bilan to'ldiriladi. Maxsus fayllar darsidagi "noma'lum slug birinchi so'rovda 200" topilmasi aynan shu qobiqdan kelib chiqqan edi.

Demak "bu sahifa statikmi?" savoli ba'zan to'liq emas. To'g'ri savol — "bu manzil statikmi?". Bitta page.tsx fayli ma'lum manzillar uchun SSG, noma'lumlari uchun PPR beradi. Next 15 da bu savolni dynamicParams sozlamasi hal qilardi; Next 16 + Cache Components'da u xato beradi — tafsiloti generateStaticParams darsida.

3. Nima sahifani dinamik qiladi?

3.1 So'rov ma'lumoti

Next 16 da qoida aniq: sahifa (yoki uning qismi) so'rovga bog'liq narsani o'qisa — u build vaqtida tayyorlanmaydi.

API Nima o'qiydi Qayerdan
cookies() Brauzer cookie'lari next/headers
headers() So'rov sarlavhalari next/headers
searchParams (sahifa prop'i) ?teg=… page.tsx
params (ro'yxatsiz) Noma'lum slug page.tsx
connection() Hech narsa — "har so'rovda" belgisi next/server
Keshsiz fetch, baza, fayl Tashqi ma'lumot —

Oxirgi qator Server Components darsidagi topilma edi: Cache Components rejimida fayl o'qish ham "keshlanmagan ma'lumot".

connection() alohida: u hech qanday qiymat qaytarmaydi. U faqat "shu joydan pastdagi kod har so'rovda bajarilsin" deydi. Math.random() yoki joriy vaqt kerak bo'lsa — undan oldin await connection().

3.2 Biz sinadik: <Suspense> siz — build xatosi

cookies() ni sahifaning tepasida, hech qanday <Suspense> siz o'qidik:

tsx
export default async function Cookie() {
  const til = (await cookies()).get("til")?.value ?? "uz";
  return <main><h1>Til: {til}</h1></main>;
}

Build:

text
Error: Route "/cookie": Next.js encountered uncached or runtime data during prerendering.
`fetch(...)`, `cookies()`, `headers()`, `params`, `searchParams`, or `connection()` accessed outside of `<Suspense>` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
Ways to fix this:
  - [stream] Provide a placeholder with `<Suspense fallback={...}>` around the data access
  - [cache] For uncached data (`fetch`, database calls): cache the access with `"use cache"` (does not apply to `connection()`)
  - [block] Set `export const instant = false` to allow a blocking route

Bu xatoni avval ham ko'rgandik — fayl o'qishda (Server Components) va Maxsus fayllar darsidagi tajribada connection() bilan. Endi uni to'liq o'qiymiz: "<Suspense> dan tashqarida o'qilgan so'rov ma'lumoti sahifani oldindan chizishga to'sqinlik qiladi, sahifa yuklanishini bloklaydi va foydalanuvchi tajribasini sekinlashtiradi". Uch yo'l:

Tanlov Nima qiladi Natija
[stream] Dinamik qismni <Suspense> ga o'rash ◐ — qobiq darhol, teshik oqimda
[cache] Ma'lumotni "use cache" bilan keshlash ○ — so'rov ma'lumotiga emas, keshlanadiganga
[block] export const instant = false ƒ — butun sahifa har so'rovda, qobiqsiz

Next 15 da bu xato yo'q edi: sahifa jimgina ƒ bo'lib qolardi. Next 16 + Cache Components "jim sekinlashish" o'rniga ochiq qaror talab qiladi. create-next-app 16.4 Cache Components'ni sukut bo'yicha yoqadi (Loyiha yaratish) — shuning uchun portfolio da bu xatoni tez-tez ko'rasiz.

Tekshirib ko'ring: cookies() ni sahifa tepasida emas, <Suspense> ichidagi kichik komponentda o'qisak, build jadvalida qaysi belgi chiqadi?

Javob

◐ — sahifa qobig'i (sarlavha, menyu, statik matn) build vaqtida tayyorlanadi, cookie'ga bog'liq kichik qism har so'rovda oqim bilan keladi. Bu — [stream] yo'li, /qisman sahifasidagidek.

4. Narx: biz o'lchadik

4.1 TTFB va sarlavhalar

Uchala sahifani next start ustida curl bilan uch martadan so'radik (TTFB — birinchi bayt kelguncha vaqt). Har qatorda uch narsaga qarang: TTFB, x-nextjs-cache va Cache-Control.

text
/statik #1 status 200 TTFB 0.006943s | x-nextjs-cache: HIT Cache-Control: s-maxage=31536000
/statik #2 status 200 TTFB 0.005000s | x-nextjs-cache: HIT Cache-Control: s-maxage=31536000
/statik #3 status 200 TTFB 0.024734s | x-nextjs-cache: HIT Cache-Control: s-maxage=31536000
/qisman #1 status 200 TTFB 0.144663s | x-nextjs-postponed: 1 Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate
/qisman #2 status 200 TTFB 0.011505s | x-nextjs-postponed: 1 Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate
/qisman #3 status 200 TTFB 0.014838s | x-nextjs-postponed: 1 Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate
/bloklovchi #1 status 200 TTFB 0.061481s | x-nextjs-postponed: 1 Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate
/bloklovchi #2 status 200 TTFB 0.012648s | x-nextjs-postponed: 1 Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate
/bloklovchi #3 status 200 TTFB 0.008546s | x-nextjs-postponed: 1 Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate

Raqamlar sizda boshqacha chiqadi (mashina, yuklama), lekin farqning shakli bir xil:

Birinchi so'rov TTFB (sovuq server)
  • ○ statiktayyor fayl7 ms
  • ƒ bloklovchihar so'rovda chiziladi61 ms
  • ◐ qismanqobiq + oqim145 ms

Manba: IlmHamroh tajribasi: next 16.4.0, next start, curl, i5-12500H, 2026-10-21

Nimani ko'ramiz:

  • Statik — 5–25 ms, x-nextjs-cache: HIT: server tayyor faylni berdi. s-maxage=31536000 — "CDN buni bir yil saqlashi mumkin". Eng tez va eng arzon: CDN'da serverga umuman yetmaydi.
  • Qisman va bloklovchi — birinchi so'rovda sekinroq (sovuq server: kod birinchi marta yuklanmoqda), keyin 8–15 ms. Cache-Control: private, no-cache, no-store — "hech kim keshlamasin": har so'rov serverga boradi.
  • Bu tajribada headers() bir zumda — dinamik qism sekin emas. Haqiqiy farq dinamik qism sekin bo'lganda ochiladi: GitHub API 150–900 ms javob bersa, ƒ sahifa shuncha kutadi, ◐ esa qobiqni darhol yuboradi. Buni Streaming darsida kanon o'lchovi bilan ko'ramiz.

Kichik g'alati narsa: ƒ /bloklovchi javobida ham x-nextjs-postponed: 1 bor. Bu ichki sarlavha — Next.js javobni oqim bilan yuborganini bildiradi; jadvaldagi belgi bilan aralashtirmang.

4.2 Qobiq HTML'da nima?

/qisman ning HTML'ida — curl bilan (JS'siz):

text
Aniqlanmoqda…
Aniqlanmoqda…
Brauzer: \",\"curl/8.19.\"]}]

Avval fallback matni (qobiqda, darhol), keyin — o'sha javobning oxirida, oqimning keyingi bo'lagida — haqiqiy qiymat (curl/8.19., payload ichida). Brauzer fallback ni ko'rsatadi va qiymat kelganda almashtiradi. Bitta HTTP javob, ikki bosqich — bu streaming (oqim). Uning ichki ishini Streaming va Suspense darsida ochamiz.

5. ISR: statik, lekin yangilanadi

ISR — "statik sahifa, lekin vaqti-vaqti bilan qayta yaratiladi". Next 16 + Cache Components'da u alohida rejim emas: "use cache" va cacheLife bilan beriladi. Server Components darsidagi blog jadvalini eslang:

text
Route (app)                         Revalidate  Expire
├ ○ /blog                                  30d      1y

/blog — ○, lekin Revalidate 30d: 30 kundan keyin keyingi so'rovda fonda qayta yaratiladi; Expire 1y — bir yildan eski nusxa umuman berilmaydi. Muddatlar cacheLife("max") dan keldi.

Next 15 dagi export const revalidate = 3600 endi ishlamaydi — kanon sinadi:

text
Error: Route segment config "revalidate" is not compatible with `nextConfig.cacheComponents`. Please remove it.

dynamic = "force-static", fetchCache, runtime — shu xato bilan. Eski segment sozlamalari va yangi model farqi — generateStaticParams va segment konfiguratsiyasi, keshlash — Cache Components I va II darslarida.

6. Qaror xaritasi

flowchart TB
  A["So'rov ma'lumoti<br/>o'qiladimi?"] -->|yo'q| S["○ statik"]
  A -->|ha| B["Bu qism keshlansa<br/>bo'ladimi?"]
  B -->|ha| C["'use cache' → ○<br/>(cacheLife — ISR)"]
  B -->|yo'q| D["Sahifaning qolgani<br/>usiz ko'rinsa bo'ladimi?"]
  D -->|ha| P["Suspense → ◐"]
  D -->|yo'q| F["instant = false → ƒ"]

Odatiy tartib: avval statik, keyin kesh, keyin ◐, va faqat oxirida ƒ. Ko'pincha ◐ eng yaxshi muvozanat: foydalanuvchi sahifani darhol ko'radi, dinamik qism esa tayyor bo'lgach keladi.

6.1 Natija oynasida: qaror funksiyasi

Yuqoridagi xaritani kod qilamiz — Next 16 + Cache Components qoidasining modeli (Next.js'ning haqiqiy kodi emas):

js
function routeSymbol(page) {
  const runtime = page.reads.some((r) =>
    ["cookies", "headers", "searchParams", "connection"].includes(r),
  );
  const data = page.reads.includes("fetch");
  if (!runtime && (!data || page.useCache)) return "○";
  if (page.inSuspense) return "◐";
  if (page.instantFalse) return "ƒ";
  return "build xatosi";
}

const pages = [
  { path: "/aloqa", reads: [] },
  { path: "/blog", reads: ["fetch"], useCache: true },
  {
    path: "/haqimda",
    reads: ["connection", "fetch"],
    inSuspense: true,
  },
  { path: "/kabinet", reads: ["cookies"], instantFalse: true },
  { path: "/cookie", reads: ["cookies"] },
];

for (const p of pages) console.log(p.path, routeSymbol(p));

Konsolda:

text
/aloqa ○
/blog ○
/haqimda ◐
/kabinet ƒ
/cookie build xatosi

/cookie — yuqoridagi haqiqiy tajriba: model ham "build xatosi" dedi. /haqimda — keyingi ikki darsda kanon aynan shunday quradi.

7. Portfolio qadami: strategiya rejasi

Bu dars, Serverda ma'lumot olish va Streaming darslari portfolio ning holat 16 ini quradi. Bugun kod o'zgarmaydi — reja tuziladi. Commit hali yo'q — u uchinchi darsda.

Holat 13 ning build jadvali — hamma sahifa statik:

Sahifa Belgi Nega
/, /aloqa, /haqimda, /loyihalar ○ So'rov ma'lumoti yo'q
/blog, /blog/<slug> ○ 30d/1y Fayl o'qish "use cache" bilan (ISR)
/loyihalar/<slug>, /rasm ○ generateStaticParams
/loyihalar/[slug] va boshqalar ◐ Noma'lum slug — qobiq

Reja: /haqimda ga GitHub bloki qo'shiladi. U har so'rovda (yoki tez-tez) yangilanishi kerak, sahifaning qolgani — yo'q. Xarita bo'yicha: keshlanmaydi (hozircha) → qolgani usiz ko'rinadi → ◐. Kanon holat 16 da aynan shunday: ◐ /haqimda, GitHub bloki <Suspense> ichida, boshida await connection(). Nega aynan connection() kerak bo'ldi (kanon topgan try/catch tuzog'i) — Serverda ma'lumot olish darsida. Keyinchalik Cache Components I darsida unga kesh qo'shiladi.

O'z jadvalingizni tuzing: npm run build chiqishidan har sahifaning belgisini oling va "nega" ustunini to'ldiring. Belgini tushuntira olmagan sahifa — kodini qayta o'qishga arziydi.

8. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
uncached or runtime data during prerendering So'rov ma'lumoti <Suspense> dan tashqarida [stream], [cache] yoki [block]
Route segment config "revalidate" is not compatible… Next 15 sozlamasi "use cache" + cacheLife
Sahifa kutilmaganda ƒ instant = false yoki tepada dinamik API Dinamik qismni pastga, Suspense ichiga
Statik sahifada eski ma'lumot Build vaqtida olingan Kesh muddati (cacheLife) yoki ◐
◐ sahifa sekin Dinamik qism sekin, lekin u qobiqni kutmaydi Bu normal; fallback'ni mazmunli qiling
CDN keshlamaydi private, no-store — dinamik javob Statikka yaqinlashtiring

9. Mashqlar

Mashqlar kurs/mashqlar/23/14-rendering/ da.

1-mashq (oson): qaysi belgi?

  • Faqat matn va rasm —
  • await cookies() sahifa tepasida, instant = false —
  • <Suspense> ichida await headers() —
  • "use cache" + cacheLife("hours") bilan fayl o'qish —
  • await searchParams tepada, hech narsasiz —
Yechim
  • ○ — so'rov ma'lumoti yo'q.
  • ƒ — [block] yo'li: butun sahifa har so'rovda.
  • ◐ — qobiq statik, teshik oqimda.
  • ○ — keshlangan ma'lumot (jadvalda Revalidate ustuni bilan).
  • build xatosi — [stream]/[block] tanlanmagan (Cache Components'da).

2-mashq (o'rta): build jadvalini o'qiydigan funksiya

Funksiya yozing: countRoutes(output) — next build chiqishidagi jadval matnini oladi va har belgidan nechta borligini qaytaradi: { "○": 9, "◐": 2, "ƒ": 0 }. Faqat Route (app) dan keyingi va bo'sh qatorgacha bo'lgan qatorlarni sanang. Ishora: split, includes.

Yechim
js
function countRoutes(output) {
  const lines = output.split("\n");
  const start = lines.findIndex((l) => l.startsWith("Route (app)"));
  const counts = { "○": 0, "◐": 0, "ƒ": 0 };
  for (const line of lines.slice(start + 1)) {
    if (line.trim() === "") break;
    for (const symbol of Object.keys(counts)) {
      if (line.includes(` ${symbol} `)) counts[symbol]++;
    }
  }
  return counts;
}

const output = `Route (app)
┌ ○ /
├ ○ /aloqa
├ ◐ /haqimda
└   /loyihalar/[slug]
  ├ ◐ /loyihalar/[slug]
  └ ○ /loyihalar/vazifalar

○  (Static)  prerendered as static content`;

console.log(countRoutes(output));

Konsolda:

text
{ '○': 3, '◐': 2, 'ƒ': 0 }

/loyihalar/[slug] sarlavha qatorida belgi yo'q — u guruh nomi, sanalmadi. Pastdagi izoh (○ (Static)…) bo'sh qatordan keyin — break uni ham sanamadi. Kanon tekshiruv skriptlari ham build jadvalini shunday "o'qiydi".

3-mashq (qiyin): qaror xaritasini kengaytiring

Qaror funksiyasini kengaytiring. «Natija oynasida: qaror funksiyasi» blokidagi routeSymbol ga ikki qoida qo'shing. (1) reads da "random" (Math.random()) bo'lsa va oldida "connection" bo'lmasa — "build xatosi" (Next 16 beqaror qiymatni prerender'da rad etadi, Hydration darsidagi new Date() kabi); (2) natija bilan birga sababini qaytaring: { symbol, reason }. Uch sahifa bilan sinang.

Yechim
js
const RUNTIME = ["cookies", "headers", "searchParams", "connection"];

function routeSymbol(page) {
  const { reads } = page;
  const randomAt = reads.indexOf("random");
  const connAt = reads.indexOf("connection");
  if (randomAt !== -1 && (connAt === -1 || connAt > randomAt)) {
    return { symbol: "build xatosi", reason: "beqaror qiymat" };
  }
  const runtime = reads.some((r) => RUNTIME.includes(r));
  const data = reads.includes("fetch");
  if (!runtime && (!data || page.useCache)) {
    return { symbol: "○", reason: "so'rov ma'lumoti yo'q" };
  }
  if (page.inSuspense) return { symbol: "◐", reason: "Suspense" };
  if (page.instantFalse) return { symbol: "ƒ", reason: "instant" };
  return { symbol: "build xatosi", reason: "qaror yo'q" };
}

const pages = [
  { path: "/sorov", reads: ["random"] },
  {
    path: "/tasodif",
    reads: ["connection", "random"],
    inSuspense: true,
  },
  { path: "/aloqa", reads: [] },
];

for (const p of pages) {
  const { symbol, reason } = routeSymbol(p);
  console.log(`${p.path}: ${symbol} (${reason})`);
}

Konsolda:

text
/sorov: build xatosi (beqaror qiymat)
/tasodif: ◐ (Suspense)
/aloqa: ○ (so'rov ma'lumoti yo'q)

Tartib muhim: connection() Math.random() dan oldin bo'lsa, tasodifiy son har so'rovda hisoblanadi — bu to'g'ri. Keyin bo'lsa — build paytida bir marta hisoblanib "muzlab" qolardi, Next shuni rad etadi. Bu — [dynamic] await connection() maslahatining ma'nosi.

4-mashq: Portfolio qadami

O'z portfolio ingizning npm run build chiqishidan strategiya jadvalini tuzing (sahifa | belgi | nega). /haqimda uchun reja yozing: qaysi qism dinamik bo'ladi, qaysi qism statik qoladi. Hali kod o'zgartirmang.

Yechim

Namuna — «Portfolio qadami» bo'limidagi jadval. Sizda ƒ belgisi bo'lsa — qaysi sahifa va nega ekanini toping: ko'pincha tepada cookies()/headers() yoki instant = false. Reja: matn, bilimlar va o'qish rejasi — statik qobiq; GitHub bloki — <Suspense> ichida dinamik teshik (◐). Kod keyingi darsda.

10. Real ishda

  • Do'kon: mahsulot tavsifi va rasmlari — statik yoki keshlangan; narx va qoldiq — tez-tez yangilanadigan kesh; "savatda 3 ta" — cookie'ga bog'liq dinamik teshik. Bitta sahifada uch strategiya.
  • Yangiliklar sayti: maqolalar — ISR (har 5–10 daqiqa), bosh sahifadagi "hozir o'qilmoqda" — dinamik.
  • Kabinet: foydalanuvchiga xos hamma narsa — dinamik; lekin menyu, footer — statik qobiqda.
  • Intervyu savoli: "SSR, SSG, ISR farqi?" va "Next.js'da sahifani nima dinamik qiladi?" — endi ikkalasiga belgilar va o'lchov bilan javob bera olasiz.

Xulosa

  • Strategiya kod bilan belgilanadi: so'rov ma'lumoti yo'q — ○, <Suspense> ichida — ◐, instant = false — ƒ.
  • cookies(), headers(), searchParams, connection(), keshsiz ma'lumot — dinamik qiladi; Next 16 da <Suspense> siz — build xatosi va uch tanlov.
  • Statik — 5–25 ms va CDN keshi; dinamik — har so'rov serverga, no-store.
  • ISR — "use cache" + cacheLife (jadvalda Revalidate/Expire); Next 15 dagi revalidate eksporti endi xato.
  • Odatiy tartib: statik → kesh → ◐ → ƒ; portfolio da /haqimda — ◐.

Keyingi dars: Serverda ma'lumot olish — GitHub API'dan profilni kalitsiz, parallel va zaxira bilan olamiz.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Next.js rendering strategiyalari: statik, dinamik va streaming (SSG, SSR, ISR, PPR) — IlmHamroh