← Guider för utvecklare
Avancerat10 min läsning

Caching i Next.js: så fungerar det

En praktisk genomgång av Next.js cachningslager: Request Memoization, Data Cache, Full Route Cache och Router Cache.

Varför caching är viktigt

En av Next.js starkaste sidor är att ramverket cachelagrar aggressivt som standard. Det innebär att databasfrågor, API-anrop och renderade sidor inte behöver upprepas i onödan, vilket direkt påverkar svarstider och serverkostnader.

Men cachning i Next.js är inte ett enda system. Det finns fyra separata lager som arbetar på olika nivåer. Att förstå var varje lager verkar gör det möjligt att felsöka oväntat beteende och välja rätt revalideringsstrategi.

Request Memoization

Request Memoization är det innersta lagret och är egentligen en React-funktion snarare än en Next.js-specifik funktion. React deduplicerar automatiskt identiska fetch()-anrop som sker under samma server-request.

Det betyder att du kan anropa samma endpoint i flera Server Components utan att oroa dig för dubbla nätverksanrop.

// Kan anropas i layout.js, page.js och valfri komponent - bara ett HTTP-anrop sker
async function hamtaAnvandare(id) {
  const res = await fetch(`https://api.exempel.se/users/${id}`);
  return res.json();
}

Memoiseringen gäller bara under en enskild request-livscykel. Nästa request börjar med tomt minne.

Data Cache

Data Cache är persistent och lever längre än en enskild request. Som standard cachelagrar Next.js alla fetch()-svar på servern tills du uttryckligen revaliderar dem.

Du styr livslängden med next.revalidate per anrop:

// Revalideras senast var 60:e sekund
const res = await fetch("https://api.exempel.se/inlagg", {
  next: { revalidate: 3600 },
});

Du kan också sätta revalidering på route-segmentnivå via en exporterad konstant i page.js eller layout.js:

export const revalidate = 3600;

För att helt skippa cachen, exempelvis för känsliga personuppgifter eller realtidsdata:

const res = await fetch("https://api.exempel.se/lager", {
  cache: "no-store",
});

Full Route Cache

Full Route Cache lagrar det renderade HTML- och RSC-payloadet för en hel route på servern. Statiskt renderade sidor cachas vid byggtid och serveras direkt utan att köra serverlogik igen.

En route är statisk om den inte använder dynamiska funktioner som cookies(), headers() eller searchParams. Så fort du introducerar ett av dessa måste Next.js rendera routen dynamiskt per request.

// Den här sidan renderas statiskt och cachas
export default async function BloggPage() {
  const inlagg = await hamtaInlagg();
  return <InlaggLista inlagg={inlagg} />;
}

Du kan verifiera vad som är statiskt respektive dynamiskt i bygglogen under next build.

Router Cache

Router Cache är det enda cachningslagret som bor i webbläsaren, inte på servern. Next.js sparar RSC-payloads i minnet på klientsidan under en navigation-session.

När användaren navigerar tillbaka till en tidigare besökt route hämtas den från Router Cache i stället för att göra ett nytt server-roundtrip. Livslängden är kort: statiska routes cachas i fem minuter, dynamiska i 30 sekunder.

Router Cache kan inte stängas av. Däremot kan du tvinga en uppdatering med router.refresh() från en Client Component.

"use client";
import { useRouter } from "next/navigation";

export function UppdateraKnapp() {
  const router = useRouter();
  return <button onClick={() => router.refresh()}>Uppdatera</button>;
}

Revalidering

Det finns två strategier för att ogiltigförklara Data Cache och Full Route Cache.

Tidsbaserad revalidering

Använd revalidate som beskrivits ovan. Next.js kör en stale-while-revalidate-princip: den gamla versionen serveras tills giltighetstiden löpt ut, sedan hämtas en ny version i bakgrunden.

On-demand revalidering

För publiceringsflöden och webhooks är on-demand revalidering mer precis. Du anropar revalidatePath() för att rensa en specifik URL eller revalidateTag() för att rensa alla fetch-anrop som taggats med en given nyckel.

import { revalidatePath, revalidateTag } from "next/cache";

// I en Route Handler eller Server Action
export async function POST(request) {
  const { slug } = await request.json();

  revalidatePath(`/blogg/${slug}`);
  revalidateTag("inlagg");

  return Response.json({ revalidated: true });
}

Taggar sätts vid fetch-anropet:

const res = await fetch("https://api.exempel.se/inlagg", {
  next: { tags: ["inlagg"] },
});

Sammanfattning

Next.js cachningsmodell bygger på fyra lager med olika livslängder och scope. Request Memoization deduplicerar anrop inom en request. Data Cache sparar fetch-svar persistent. Full Route Cache lagrar renderade sidor på servern. Router Cache sparar navigationshistorik i webbläsaren. Förstår du var ett problem uppstår i kedjan blir felsökning och revalidering mycket enklare.

Kevin Sommerstein
Kevin SommersteinGrundare, Developly

Medgrundare av Developly Sweden och webbutvecklare med 8 års erfarenhet inom JavaScript, React och Next.js.

LinkedIn →