Neljä välimuistia: pyyntö, data, koko reitti ja reititin
Selvittäkää, miten kukin välimuistikerros toimii yhdessä muiden kanssa ja mistä vanhentunut data syntyy App Router -sovelluksissa.
Neljä välimuistia: pyyntö, data, koko reitti ja reititin on ilmainen Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Next.js 15 -fullstack-kehitys (App Router + Server Actions)-kurssilla on yhteensä 4 oppituntia.
Neljä välimuistia, yksi ajattelumalli
Next.js 15:n App Routerissa on neljä erillistä välimuistikerrosta. Vanhentunut data on lähes aina peräisin jostakin niistä, joten niiden täsmällinen nimeäminen on vianmäärityksen ensimmäinen vaihe.
- Request Memoization — poistaa identtisten
fetch-kutsujen päällekkäisyyden yhden renderöintikierroksen aikana. - Data Cache — säilyttää
fetch-tulokset pyyntöjen ja käyttöönottojen välillä palvelimella pysyvästi. - Full Route Cache — tallentaa staattisesti renderöityjen reittien HTML:n ja RSC-hyötykuorman käännösvaiheessa.
- Router Cache — selaimen muistissa oleva asiakaspuolen välimuisti vierailtujen reittien RSC-hyötykuormille.
Ne toimivat suunnilleen asiakkaasta palvelimelle: Router Cache sijaitsee selaimessa ja kolme muuta palvelimella.
Taso 1: Request Memoization
Request Memoization on Reactin sisäänrakennettu fetch-kutsujen päällekkäisyyksien poisto yhden palvelinrenderöinnin aikana. Jos kolme komponenttia pyytää samaa URL-osoitetta samoilla asetuksilla, verkkokutsu suoritetaan kerran; muut käyttävät samaa käynnissä olevaa promisea.
- Laajuus: yksi renderöintikierros eli yksi pyyntö. Sitä ei jaeta pyyntöjen välillä.
- Avain:
fetch-kutsu ja sen asetukset. - Hyöty: voitte kutsua
getUser()-funktiota sekä layoutissa että sivulla ilman propsien välittämistä kerroksesta toiseen tai uutta hakua.
Vain fetch memoisoidaan automaattisesti. Muun kuin fetch-työn, kuten tietokanta-asiakkaiden ja ORM:ien, voitte kääriä Reactin cache()-funktion sisään.
import { cache } from 'react';
import { db } from '@/lib/db';
// Without fetch, memoize manually so layout + page share one query
export const getUser = cache(async (id: string) => {
return db.user.findUnique({ where: { id } });
});
// Both calls in the same render hit the DB only once
async function Layout({ id }: { id: string }) {
const user = await getUser(id);
return user.name;
}Memoointi koskee renderöintiä, ei pysyvää tallennusta
Yleinen väärinkäsitys on ajatella, että Request Memoization säilyttää dataa. Se ei säilytä. Heti kun renderöinti päättyy, memovälimuisti hylätään.
- Se on olemassa vain päällekkäisen työn välttämiseksi yhden renderöintipuun sisällä.
- Seuraava saapuva pyyntö aloittaa tyhjällä memovälimuistilla.
- Pyyntöjen yli ulottuvasta pysyvyydestä vastaa Data Cache, ei memoointi.
Jos näette pyynnössä A tuoretta dataa mutta sama renderöinti käyttää sitä uudelleen, kyse on memooinnista. Jos data säilyy palvelimen uudelleenkäynnistyksen jälkeen, kyse on Data Cache -välimuistista.
Taso 2: Data Cache
Data Cache säilyttää fetch-tulokset palvelimella pyyntöjen, käyttäjien ja jopa käyttöönottojen välillä, kunnes välimuisti päivitetään. Next.js 15:ssä oletusasetus muuttui: fetch on nyt oletusarvoisesti välimuistiton (no-store), ellei välimuistia oteta käyttöön erikseen.
cache: 'force-cache'→ tallenna tulos ja käytä sitä uudelleen.next: { revalidate: N }→ tallenna tulos, tarjoa vanhentunutta dataa enintään N sekunnin ajan ja päivitä sitten.cache: 'no-store'→ älä tallenna koskaan, vaan hae aina lähteestä.
Tämä on yleensä se kerros, joka aiheuttaa kysymyksen ”miksi datani on vanhentunutta?”, kun ette huomaa datan olevan välimuistissa.
// Next.js 15: opt INTO the Data Cache explicitly
async function getProducts() {
// Revalidate at most every 60s (ISR-style)
const res = await fetch('https://api.shop.com/products', {
next: { revalidate: 60 },
});
return res.json();
}
async function getCart() {
// Per-user, never cache
const res = await fetch('https://api.shop.com/cart', {
cache: 'no-store',
});
return res.json();
}Tagaus ja kohdennettu päivitys
Data Cache tukee välimuistitunnisteita, joiden avulla voitte mitätöidä täsmälleen tiettyyn dataan liittyvät merkinnät — tämä on ihanteellista sen jälkeen, kun Server Action on muuttanut tietokantaa.
- Liittäkää tunnisteet
fetch-kutsun yhteydessä:next: { tags: ['products'] }. - Mitätöikää tunnisteen perusteella kutsumalla
revalidateTag('products'). - Mitätöikää polun perusteella kutsumalla
revalidatePath('/products').
Molemmat funktiot suoritetaan palvelimella (Server Actionissa tai Route Handlerissa), ja ne tyhjentävät Data Cachen sekä kyseisten reittien Full Route Cache -merkinnät.
'use server';
import { revalidateTag } from 'next/cache';
import { db } from '@/lib/db';
export async function createProduct(formData: FormData) {
await db.product.create({
data: { name: String(formData.get('name')) },
});
// Purge every fetch tagged 'products' → next read is fresh
revalidateTag('products');
}Taso 3: Full Route Cache
Full Route Cache tallentaa reitin kokonaan renderöidyn tuloksen — sekä HTML:n että React Server Component (RSC) -hyötykuorman — palvelimelle käännösvaiheessa. Se koskee vain staattisesti renderöityjä reittejä.
- Reitti on staattinen, ellei se käytä dynaamisia API-rajapintoja (
cookies(),headers(),searchParams) tai välimuistitontafetch-kutsua. - Staattiset reitit tarjotaan tästä välimuistista heti ilman uutta renderöintiä.
- Dynaamiset reitit ohittavat Full Route Cachen ja renderöidään jokaisen pyynnön yhteydessä.
Ajatelkaa sitä Data Cachen renderöidyn tuloksen vastineena: Data Cache sisältää raakaa fetch-dataa.
Staattinen vs. dynaaminen: mikä käynnistää kummankin
Se, päätyykö reitti Full Route Cacheen, riippuu siitä, mitä se käyttää renderöinnin aikana. Dynaamisen API-rajapinnan lukeminen tekee koko reitistä dynaamisesti renderöitävän.
cookies()-,headers()-,draftMode()- taisearchParams-käyttö → dynaaminen.fetch, jossa oncache: 'no-store'→ dynaaminen.export const dynamic = 'force-dynamic'→ aina dynaaminen.
Voitte pakottaa vastakkaisen suunnan käyttämällä export const dynamic = 'force-static' -määritystä, jolloin reitti säilyy välimuistissa.
// This page becomes DYNAMIC because it reads cookies()
import { cookies } from 'next/headers';
export default async function Dashboard() {
const store = await cookies(); // Next.js 15: cookies() is async
const theme = store.get('theme')?.value ?? 'light';
// Full Route Cache is skipped; rendered fresh per request
return <main data-theme={theme}>Welcome back</main>;
}Taso 4: Router Cache (asiakas)
Router Cache on muistissa oleva asiakaspuolen RSC-hyötykuormien säilö reiteille, joilla käyttäjä on vieraillut tai jotka hän on esiladannut. Se tekee edelliselle ja seuraavalle sivulle siirtymisestä välitöntä ja välttää uudelleenhaun pehmeiden navigointien yhteydessä.
- Se sijaitsee selaimessa ja tyhjennetään, kun koko sivu ladataan uudelleen.
- Siksi
<Link>-linkin kautta takaisin sivulle siirryttäessä näkyviin tulee edellinen hyötykuorma, vaikka palvelimen data olisi muuttunut. - Next.js 15:ssä sivusegmenttien oletusarvoinen
staleTimeon 0, joten dynaamiset sivut haetaan oletusarvoisesti uudelleen navigoinnin yhteydessä.
Tämä on useimmiten hämmennystä aiheuttava kerros: palvelin on jo päivittänyt välimuistin, mutta asiakas näyttää edelleen vanhaa käyttöliittymää Router Cachesta.
Router Cachen tyhjentäminen mutaation jälkeen
Pelkkä palvelinpuolen välimuistin päivitys ei päivitä asiakkaan Router Cachea. Server Actionin jälkeen myös asiakasvälimuisti on mitätöitävä.
- Server Actionin sisällä kutsutut
revalidatePath- jarevalidateTag-funktiot merkitsevät myös Router Cachen vanhentuneeksi, joten seuraava navigointi hakee datan uudelleen. useRouter-hookinrouter.refresh()tyhjentää Router Cachen ja renderöi nykyisen reitin palvelinkomponentit uudelleen.- Koko sivun uudelleenlataus tyhjentää Router Cachen kokonaan.
Kun yhdistätte Server Actionin revalidateTag-kutsun evästepohjaiseen action-vastaukseen, sekä palvelin että asiakas pysyvät ajan tasalla.
'use client';
import { useRouter } from 'next/navigation';
export function RefreshButton() {
const router = useRouter();
return (
<button onClick={() => router.refresh()}>
Reload server data
</button>
);
}Yhden pyynnön jäljittäminen kaikkien neljän kerroksen läpi
Seuratkaa yhtä navigointia nähdäksenne, miten kerrokset toimivat yhdessä:
- 1. Router Cache (asiakas): jos tuore hyötykuorma on olemassa, renderöi se heti — lopeta tähän.
- 2. Full Route Cache (palvelin): onko reitti staattinen? Tarjoa välimuistissa oleva HTML/RSC.
- 3. Data Cache (palvelin): dynaaminen renderöinti lukee
fetch-tulokset täältä, jos ne ovat välimuistissa ja voimassa. - 4. Request Memoization: saman renderöinnin sisällä päällekkäiset fetch-kutsut yhdistetään yhdeksi.
Vanhentunut data on peräisin siitä kerroksesta, joka vastasi ensimmäisenä. Selvittäkää ongelmaa ylhäältä alaspäin: sulkekaa Router Cache pois ennen palvelimen epäilemistä.
Puhdas TypeScript-analogia memooinnille
Request Memoization on käsitteellisesti argumenttien perusteella avaimettu renderöintikohtainen memo. Tässä on sama idea tavallisena TypeScriptinä, jota voitte suorittaa ja jonka toimintaa voitte tarkastella — se poistaa samanaikaisten kutsujen päällekkäisyyden tallentamalla käynnissä olevan promisen.
Varsinainen Next.js-versio tyhjentää tämän mapin jokaisen renderöinnin yhteydessä; tämä esimerkki säilyttää sen ohjelman koko eliniän ajan.
function memoize<T>(fn: (k: string) => Promise<T>) {
const inFlight = new Map<string, Promise<T>>();
return (key: string): Promise<T> => {
if (!inFlight.has(key)) inFlight.set(key, fn(key));
return inFlight.get(key)!;
};
}
let calls = 0;
const load = memoize(async (k: string) => {
calls++;
return `data:${k}`;
});
async function main() {
const [a, b] = await Promise.all([load('x'), load('x')]);
console.log(a, b, 'network calls =', calls);
}
main();Pikatarkistus: vanhentunut käyttöliittymä Server Actionin jälkeen
Suoritatte Server Actionin, joka luo tuotteen ja kutsuu revalidateTag('products')-funktiota. Palvelimen Data Cache ja Full Route Cache ovat nyt ajan tasalla, mutta käyttäjä, joka siirtyy takaisin <Link>-linkin kautta, näkee edelleen vanhan luettelon. Mikä kerros tarjoaa vanhentunutta dataa?
Kertaus: neljä välimuistia
Osaatte nyt sijoittaa minkä tahansa vanhentuneen datan ongelman oikeaan kerrokseen:
- Request Memoization — renderöintikohtainen fetch-kutsujen päällekkäisyyksien poisto; hylätään renderöinnin jälkeen; laajennettavissa muuhun kuin fetch-työhön
cache()-funktiolla. - Data Cache — pysyvä, pyyntöjen yli ulottuva fetch-tulosten tallennus; otetaan käyttöön asetuksilla
force-cache/revalidate; tyhjennetään kutsuillarevalidateTag/revalidatePath. - Full Route Cache — staattisten reittien renderöity HTML/RSC; dynaamiset API:t poistavat reitin käytöstä.
- Router Cache — vierailtujen reittien asiakaspuolen RSC-hyötykuormat; tyhjennetään päivityksellä tai kutsulla
router.refresh().
Selvittäkää ongelmaa ylhäältä alaspäin (asiakkaasta palvelimelle): sulkekaa ensin Router Cache pois, sitten Full Route Cache, Data Cache ja lopuksi memoointi.
Opi TypeScript tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 22
- Oppitunnit
- 88
Usein kysytyt kysymykset
Onko oppitunti ”Neljä välimuistia: pyyntö, data, koko reitti ja reititin” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppimispolun 3 oppituntia, myös oppitunnin “Neljä välimuistia: pyyntö, data, koko reitti ja reititin”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Next.js 15 -fullstack-kehitys (App Router + Server Actions)-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Neljä välimuistia: pyyntö, data, koko reitti ja reititin”?
Selvittäkää, miten kukin välimuistikerros toimii yhdessä muiden kanssa ja mistä vanhentunut data syntyy App Router -sovelluksissa. Harjoittelet Next.js 15 -fullstack-kehitys (App Router + Server Actions)-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Next.js 15 -fullstack-kehitys (App Router + Server Actions)-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Neljä välimuistia: pyyntö, data, koko reitti ja reititin”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppitunnilla?
Kyllä. Jokainen Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Neljä välimuistia: pyyntö, data, koko reitti ja reititin
- Aikaperusteiset ja tarpeen mukaan tehtävät uudelleenvalidointistrategiat
- Tunnistepohjainen mitätöinti tarkkaan välimuistin tyhjennykseen
- Välimuistin ohittaminen: dynaaminen renderöinti ja no-store