We help companies like yours with expert Next.js performance advice and auditing.

Performance Tuning
07/05/2025 08:59

Next.js Page Data: Deep Dive and Performance Insights

How to analyze and reduce page data size in Next.js for better performance and faster hydration

media

Next.js Page Data: Deep Dive and Performance Insights

What Exactly Is “Page Data” in Next.js?

In Next.js, "page data" refers to the JSON-serialized props and metadata tied to a page during Server-Side Rendering (SSR) or Static Site Generation (SSG). This is the data you return from getStaticProps, getServerSideProps, etc., which Next.js then serializes into JSON for client-side use.

In traditional Next.js applications (Pages Router, Next.js 12 and earlier), this page data is embedded in the HTML within a special <script> tag with the ID __NEXT_DATA__. If you're using SSG, it’s also saved as a .json file in the /_next/data/ directory.

In newer applications using the App Router (Next.js 13+), the process changes slightly: smaller script tags inject page data chunks by calling self.__next_f.push(), aiming for a more granular and efficient loading experience.

Ideal Page Data Size and Performance Impact

Because page data is parsed on the client, its size directly impacts performance. Ideally, your page data should be as lean as possible — just enough to render the first view.

Next.js will warn you if your page data exceeds 128 kB, a threshold chosen because larger payloads can noticeably delay hydration.

Inspecting and Measuring Page Data Size

How to Inspect Page Data Size

Before you optimize, you need to measure. Here's how you can inspect page data:

Pages Router:

  • Open DevTools and find the <script id="__NEXT_DATA__" type="application/json"> tag.
  • Or, in the console, inspect the page data directly: console.log(window.__NEXT_DATA__);

To measure its size:

console.log('Page data size (kB):', new TextEncoder().encode(document.getElementById('__NEXT_DATA__').textContent).length / 1024);

App Router:

  • Look for multiple <script> tags containing self.__next_f.push.

To estimate size, you can run:

console.log('Page data size (kB):', new TextEncoder().encode(JSON.stringify(window.__next_f)).length / 1024);

Strategies to Reduce Page Data Size

If your page data is bloated, here are some detailed strategies to reduce it:

1. Return Only Essential Data

This is the most critical rule. Carefully review what you return in getStaticProps and getServerSideProps. Only include the fields necessary for the first render. Avoid sending large, unnecessary objects, and especially avoid inlining large assets (like base64-encoded images or SVGs). If extra data is needed later, fetch it client-side after the page has hydrated.

2. Paginate or Lazy-Load Large Data Sets

If your page naturally wants to show a lot of data reconsider the UX. Perhaps implement pagination or infinite scroll, where getStaticProps only returns the first N items and subsequent items are fetched via an API route when the user scrolls. This way, initial page data stays small. Next.js supports dynamic routes and can generate pages for, say, /products/page/2. Alternatively, load additional chunks of data on the client side using a data fetching library (like SWR or React Query) after hydration.

3. Dynamically Import Data-Heavy Components

Sometimes a large page data payload comes from a heavy component that isn't critical for the initial render. For example, an interactive graph.

In this case, dynamically import the component with ssr: false:

const Graph = dynamic(() => import('../components/Graph'), { ssr: false });

The initial page data shrinks, and the graph appears slightly after page load (you can show a spinner or placeholder). This technique essentially opts certain parts of the page out of SSR to keep the critical payload light. Use this with caution: only do it for non-critical or non-blocking parts of the UI, since you are trading some initial completeness for performance.

4. Leverage React Server Components (Next.js 13+)

If you're using the App Router, React Server Components can be a game changer. Server Components fetch and render data directly on the server, meaning the data doesn't even touch the client as JSON. Instead, it gets embedded as HTML.

This approach reduces page payloads dramatically because there's no hydration required for server components — only client components (those using "use client") need serialized props.

Converting heavy data-driven parts of your page into Server Components helps you minimize reliance on __NEXT_DATA__ or self.__next_f.push, aligning with Next.js’s goal of reducing client-side JavaScript and improving Time to Interactive (TTI).

It’s worth noting that any data you do keep in page data is fully available to the client so make sure to never include any secrets. But for performance, think of page data as precious: every byte is delaying your user from seeing or interacting with the page. As one Next.js maintainer put it, only return the data that is needed to hydrate the page (first render) – any additional data can be loaded on client-side or on client transition.

Our experts in Next.js performance can help you improve the speed and performance of your app.Get in touchto learn how we can help.

Get Your Free Consultation Today

Don’t let a slow Next.js app continue to impact your commercial goals. Get a free consultation
with one of our performance engineers and discover how you can achieve faster load times,
happier customers, and a significant increase in your key commercial KPIs.