Go to the homepage
Powered bySitecore Search logo
Skip to main contentThe Data Fetching Optimization for Next.js Applications page has loaded.

Data Fetching Optimization for Next.js Applications

Context

In XM Cloud applications built with Next.js, performance can be impacted by the data fetching strategy utilized. Inappropriate data fetching methods can lead to slow page loads, excessive server load, and poor user experience. Many developers default to client-side fetching without considering the performance implications, or use server-side rendering when static generation would be more efficient.

Execution

Next.js offers multiple data fetching methods, each with distinct performance characteristics. Selecting the right method for your XM Cloud content is critical.

Static Site Generation (SSG) with Incremental Static Regeneration (ISR)

SSG with Incremental Static Regeneration (ISR) is ideal for scenarios where content changes infrequently and can be pre-rendered at build time. It works well for marketing pages, product listings, and general content pages where the information remains largely static. Since these pages do not require real-time personalization and present the same content to all users, SSG ensures optimal performance and scalability. Additionally, for websites where SEO is a priority, pre-rendering pages ahead of time improves search engine indexing and ranking, making it a powerful approach for delivering fast, highly optimized experiences.

Setting this up has 2 clear impacts -

PerformanceSEO
  • Pages load instantly from CDN after initial generation
  • Better Core Web Vitals scores compared to SSR
  • Reduced server load through caching
  • Automatic background regeneration ensures content freshness
  • Delivers complete HTML to search engine crawlers
  • Provides fast Time to First Byte (TTFB), a positive SEO signal
  • Ensures consistent content for indexing
  • Maintains optimal Core Web Vitals scores, which directly affect search rankings

Incremental Static Regeneration(ISR) is enabled by default - This means your XM Cloud pages automatically benefit from:

  • Static page generation at build time
  • Background revalidation every 5 seconds (configurable)
  • On-demand page generation for new routes

You don't need to implement this yourself - it's already set up in the XM Cloud Front End Application Starter Kits. The key configuration is in the getStaticProps function where revalidate: 5 enables ISR.

Key Performance Optimizations

  • Incremental Static Regeneration provides the page performance of static generation with the content freshness of server-side rendering. Teams will need to appropriate set this revalidate value.
  • The revalidate: 5 setting enables Incremental Static Regeneration (ISR), which serves cached pages while regenerating them in the background. This provides the page performance of static generation with the content freshness of server-side rendering. Teams will need to appropriate set this revalidate value.
  • Using fallback: 'blocking' means that when a page is requested that hasn't been generated yet, the user waits for the page to be rendered on the server once before being served. This is preferred for content where SEO is important.
  • Conditional Path Generation allows for parts of site to be pre-generated, while other parts will be server-side rendered. Note: this is only for production, not in development.
  • Using ComponentPropsContext to efficiently pass props to deeply nested components without prop drilling.

Server-Side Rendering (SSR) When Needed

Server-Side Rendering (SSR) in XM Cloud is best suited for scenarios that require user-specific content. It is essential for pages that rely on real-time data updates, ensuring users always see the latest information. SSR is also necessary when request-time details, such as cookies or headers, influence the page's content. Additionally, it provides access to the Sitecore Context, enabling session tracking and user-specific personalization capabilities. For protected content, authentication checks can be performed on each request, ensuring only authorized users can access sensitive information. This makes SSR a powerful approach for delivering dynamic, personalized, and secure experiences.

Setting this up has 2 clear impacts -

PerformanceSEO
  • SSR adds server processing time to each request
  • Consider adding caching headers for browsers and CDNs
  • For pages with high traffic but infrequent content changes, consider ISR instead
  • Provides complete server-rendered HTML to search engines
  • Works well for personalized content while maintaining SEO benefits
  • May have slightly higher TTFB compared to SSG
  • Requires careful performance optimization to maintain good Core Web Vitals
  • For optimal SEO while using SSR, consider setting appropriate caching headers and optimise server response times. See On-page SEO Optimization recipe for further information.

You can create a dedicated route handler. For example, if you want all pages under a "live-data" section to use SSR:

// pages/live-data/[[...path]].tsx // Any page you can create under “home -> livedata -> ” would be served through SSR. // Implement the SSR import { useEffect } from 'react'; import { GetServerSideProps } from 'next'; import NotFound from 'src/NotFound'; import Layout from 'src/Layout'; import { SitecoreContext, ComponentPropsContext, EditingComponentPlaceholder, RenderingType } from '@sitecore-jss/sitecore-jss-nextjs'; import { handleEditorFastRefresh } from '@sitecore-jss/sitecore-jss-nextjs/utils'; import { SitecorePageProps } from 'lib/page-props'; import { sitecorePagePropsFactory } from 'lib/page-props-factory'; import { componentBuilder } from 'temp/componentBuilder'; const SitecorePage = ({ notFound, componentProps, layoutData, headLinks }: SitecorePageProps) => { console.log("Inside LiveData => SitecorePage", layoutData); useEffect(() => { handleEditorFastRefresh(); }, []) if(notFound || !layoutData?.sitecore?.route){ return <NotFound></NotFound> } const isEditing = layoutData.sitecore.context.pageEditing; const isComponentRendering = layoutData.sitecore.context.renderingType === RenderingType.Component; return ( <ComponentPropsContext value={componentProps}> <SitecoreContext componentFactory={componentBuilder.getComponentFactory({ isEditing })} layoutData={layoutData}> {isComponentRendering ? ( <EditingComponentPlaceholder rendering={layoutData?.sitecore?.route} /> ) : ( <Layout layoutData={layoutData} headLinks={headLinks} /> )} </SitecoreContext> </ComponentPropsContext> ) } export const getServerSideProps: GetServerSideProps = async (context) => { console.log("Inside server side props: LiveData"); if (context.params) context.params.path = context.resolvedUrl; const props = await sitecorePagePropsFactory.create(context); return { props, notFound: props.notFound } } export default SitecorePage;

Insights

While the Getting Component Specific Data recipe covers implementation details, here are key performance advantages of component level data fetching.

AdvantageDetail
Parallel Data Loading
  • Components fetch their data independently
  • Multiple API calls can execute simultaneously
  • Reduces overall page load time compared to sequential page-level fetching
Optimized Data Transfer
  • Components only fetch the data they need
  • Reduces unnecessary network payload
  • Improves initial page load performance
Enhanced Caching
  • Component-specific data can be cached independently
  • Different cache durations for different types of content
  • More granular cache invalidation strategies

© Copyright 2025, Sitecore. All Rights Reserved

Legal

Privacy

Get Help

LLM