Bird
Raised Fist0
NextJSframework~8 mins

ISR (Incremental Static Regeneration) in NextJS - Performance & Optimization

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Performance: ISR (Incremental Static Regeneration)
MEDIUM IMPACT
ISR affects page load speed by serving static pages quickly while updating content in the background without blocking user requests.
Serving frequently updated content with fast page loads
NextJS
export async function getStaticProps() {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();
  return { props: { data }, revalidate: 60 };
}

// Page served statically and regenerated in background every 60 seconds
Serves cached static page instantly and updates content in background without blocking users.
📈 Performance GainLCP improved by 300-400ms, reduces server load, non-blocking regeneration
Serving frequently updated content with fast page loads
NextJS
export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();
  return { props: { data } };
}

// Page renders on every request, blocking user until data loads
Blocks page rendering on every request causing slower load times and higher server load.
📉 Performance CostBlocks rendering for 200-500ms per request depending on API speed
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
Server-side rendering on every requestHigh (new DOM each request)Multiple reflows per requestHigh paint cost due to delay[X] Bad
ISR with revalidate optionLow (cached DOM reused)Single reflow on initial loadLow paint cost, fast LCP[OK] Good
Rendering Pipeline
ISR serves a pre-built static HTML page immediately (fast Style Calculation, Layout, Paint). Meanwhile, regeneration happens asynchronously on the server, so user requests are not delayed.
Network
Style Calculation
Layout
Paint
⚠️ BottleneckServer regeneration can be slow but happens off the critical path
Core Web Vital Affected
LCP
ISR affects page load speed by serving static pages quickly while updating content in the background without blocking user requests.
Optimization Tips
1Use ISR to serve static pages instantly and regenerate content in the background.
2Set revalidate time based on how fresh your content needs to be.
3Avoid blocking user requests by never regenerating pages synchronously on request.
Performance Quiz - 3 Questions
Test your performance knowledge
How does ISR improve page load performance compared to server-side rendering?
ABy serving cached static pages instantly and regenerating in the background
BBy regenerating pages on every user request synchronously
CBy loading all data on the client side after page load
DBy disabling caching completely
DevTools: Performance
How to check: Record page load and look for long tasks blocking main thread. Check if initial HTML is served quickly and regeneration happens after.
What to look for: Fast Time to First Byte (TTFB) and short Largest Contentful Paint (LCP) indicate good ISR performance.

Practice

(1/5)
1. What is the main purpose of Incremental Static Regeneration (ISR) in Next.js?
easy
A. To disable static generation completely
B. To generate pages only on the client side
C. To update static pages after build without rebuilding the entire site
D. To force server-side rendering on every request

Solution

  1. Step 1: Understand ISR concept

    ISR allows static pages to be updated after the initial build without rebuilding the whole site.
  2. Step 2: Compare options

    Options B, C, and D describe client-side rendering, disabling static generation, or forcing server-side rendering, which are not ISR features.
  3. Final Answer:

    To update static pages after build without rebuilding the entire site -> Option C
  4. Quick Check:

    ISR updates static pages incrementally = A [OK]
Hint: ISR updates static pages without full rebuilds [OK]
Common Mistakes:
  • Confusing ISR with client-side rendering
  • Thinking ISR disables static generation
  • Believing ISR forces server-side rendering
2. Which Next.js function should you use to enable ISR by specifying a revalidation time?
easy
A. getServerSideProps
B. getStaticProps
C. getInitialProps
D. useEffect

Solution

  1. Step 1: Identify ISR enabling function

    ISR is enabled by returning a revalidate property inside getStaticProps.
  2. Step 2: Check other options

    getServerSideProps is for server-side rendering, getInitialProps is legacy, and useEffect is a React hook for client-side effects.
  3. Final Answer:

    getStaticProps -> Option B
  4. Quick Check:

    ISR uses getStaticProps with revalidate = D [OK]
Hint: Use getStaticProps with revalidate for ISR [OK]
Common Mistakes:
  • Using getServerSideProps instead of getStaticProps
  • Confusing client-side hooks with data fetching
  • Using deprecated getInitialProps for ISR
3. Given this code snippet, what will be the behavior of the page?
export async function getStaticProps() {
  return {
    props: { time: Date.now() },
    revalidate: 10,
  };
}
medium
A. The page throws a syntax error
B. The page never updates after build
C. The page updates on every request
D. The page updates every 10 seconds with new time

Solution

  1. Step 1: Analyze revalidate property

    The revalidate: 10 means Next.js will regenerate the page at most every 10 seconds.
  2. Step 2: Understand page update behavior

    The page will serve the static content initially, then update the static page in the background every 10 seconds.
  3. Final Answer:

    The page updates every 10 seconds with new time -> Option D
  4. Quick Check:

    revalidate 10 means update every 10 seconds = A [OK]
Hint: revalidate sets update interval in seconds [OK]
Common Mistakes:
  • Thinking page never updates after build
  • Confusing ISR with server-side rendering
  • Assuming syntax error due to revalidate
4. Identify the error in this ISR setup:
export async function getStaticProps() {
  return {
    props: { data: 'Hello' },
    revalidate: '60',
  };
}
medium
A. revalidate must be a number, not a string
B. props must be a function, not an object
C. getStaticProps cannot be async
D. Missing fallback property

Solution

  1. Step 1: Check revalidate type

    The revalidate property must be a number representing seconds, not a string.
  2. Step 2: Verify other parts

    props is correctly an object, getStaticProps can be async, and fallback is unrelated here.
  3. Final Answer:

    revalidate must be a number, not a string -> Option A
  4. Quick Check:

    revalidate type must be number = C [OK]
Hint: revalidate must be numeric seconds, not string [OK]
Common Mistakes:
  • Passing revalidate as string instead of number
  • Thinking getStaticProps can't be async
  • Confusing fallback with revalidate
5. You want a blog page to update its static content every 5 minutes but also show a fallback loading page on first visit to new posts. Which ISR setup is correct?
hard
A. Use getStaticProps with revalidate: 300 and fallback: 'blocking' in getStaticPaths
B. Use getServerSideProps with revalidate: 300
C. Use getStaticProps with revalidate: '300' and no fallback
D. Use getStaticPaths with fallback: false and no revalidate

Solution

  1. Step 1: Understand ISR with fallback

    To update static pages every 5 minutes (300 seconds) and show fallback loading for new pages, use revalidate: 300 in getStaticProps and fallback: 'blocking' in getStaticPaths.
  2. Step 2: Check other options

    Use getServerSideProps with revalidate: 300 uses server-side rendering, not ISR. Use getStaticProps with revalidate: '300' and no fallback has revalidate as string and no fallback. Use getStaticPaths with fallback: false and no revalidate disables fallback and revalidate, so no ISR updates or loading fallback.
  3. Final Answer:

    Use getStaticProps with revalidate: 300 and fallback: 'blocking' in getStaticPaths -> Option A
  4. Quick Check:

    ISR with fallback blocking and revalidate 300 = B [OK]
Hint: Combine revalidate with fallback: 'blocking' for ISR + loading [OK]
Common Mistakes:
  • Using server-side rendering instead of ISR
  • Passing revalidate as string
  • Setting fallback to false disables loading fallback