Skip to Content

Next.js Performance Analytics — Client & Server Usage Guide

Overview

Performance in a Next.js application depends on multiple factors such as JavaScript bundle size, server component efficiency, navigation speed, image optimization, script loading, and key Web Vitals metrics. Proper monitoring and optimization in these areas ensures your app is fast, responsive, and SEO-friendly.


Client-Side Performance Checks

On the client side, performance issues often arise from heavy JavaScript bundles, inefficient client components, and unoptimized resource loading.

1. JavaScript Bundle Size

Large bundles slow page load and interactivity.

npm install @next/bundle-analyzer

next.config.js:

const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true', }); module.exports = withBundleAnalyzer({});
ANALYZE=true npm run build

Checks:

  • Look for large libraries (MUI, Lodash, Chart.js)
  • Repeated code across chunks
  • Unoptimized imports

Fixes:

  • Convert components to Server Components where possible
  • Lazy-load heavy components with dynamic()
  • Tree-shake libraries
  • Remove unused dependencies

2. Navigation Lag

Lag happens when route changes trigger heavy re-renders or unnecessary fetches.

Checks:

  • Are data fetching calls repeated on every route change?
  • Are layouts heavy or contain many client components?

Fixes:

  • Use React Suspense with loading.js
  • Cache requests (fetch(..., { cache: "force-cache" }))
  • Keep layouts lightweight
  • Move heavy logic to server components

3. Images & Scripts

Images (next/image)

Optimized images improve LCP and reduce CLS.

Best Practices:

  • Set width and height to prevent layout shifts
  • Use priority for hero images
  • Use placeholder="blur" for smoother loading
  • Include alt for SEO

Scripts (next/script)

Strategy Options:

StrategyLoads WhenUse Case
beforeInteractiveImmediatelyCritical scripts
afterInteractiveAfter hydrationAnalytics
lazyOnloadIdle timeAds, trackers

Fixes:

  • Avoid blocking hydration
  • Load non-critical scripts lazily
  • Minimize main-thread work

Server-Side Performance (SSR/SSG)

Server-side performance affects TTFB, LCP, and overall page load.

1. Server Components

Checks:

  • Are heavy computations inside server components?
  • Are large datasets fetched without caching?

Fixes:

  • Cache queries (revalidate, Redis, or CDN)
  • Split heavy logic into smaller components
  • Paginate large datasets
  • Use server actions for mutations

2. Prefetching Data

Prefetch data during SSR to reduce client-side fetching and improve UX.

import { QueryClient, dehydrate } from '@tanstack/react-query' const queryClient = new QueryClient() await queryClient.prefetchQuery({ queryKey: ['users'], queryFn: () => fetch('/api/users').then(res => res.json()) }) const dehydratedState = dehydrate(queryClient)
  • Use HydrationBoundary to pass the prefetched data to the client
  • Prevents unnecessary network requests after initial render

Core Performance Metrics (Web Vitals)

Next.js provides the useReportWebVitals hook to monitor performance:

import { useReportWebVitals } from 'next/web-vitals' useReportWebVitals(metric => console.log(metric))

Or you can use Lighthouse  extension to look further into this performance metrics.

Metrics Overview

MetricDescriptionTargetWhy It MattersCommon CausesFixes
LCPLargest Content full Paint: time until the largest visible element renders< 2.5sMeasures perceived load speedLarge images, slow server response, render-blocking JS/CSSOptimize images, cache server responses, reduce JS bundle, use Server Components
INPInteraction to Next Paint: responsiveness to user input< 200msMeasures interactivityHeavy JS, hydration delay, client-side re-rendersMove logic to server, memoize components, virtualize lists
CLSCumulative Layout Shift: layout stability< 0.1Prevents visual jankImages without dimensions, font swap, dynamic contentSet width/height, use font-display swap, reserve layout space
TBTTotal Blocking Time: main-thread blocking by JS< 300msAffects interactivity and INPLarge JS bundles, heavy hydrationSplit JS, lazy-load components, convert to Server Components
Hydration TimeTime for React to attach to SSR HTMLFast as possibleAffects time to interactiveMany client components, heavy JSReduce client components, dynamic imports, partial hydration

For the most up-to-date and detailed information, please refer to the official documentation:


Summary Checklist

AreaWhat to MonitorCommon Fixes
Bundle sizeJS size, librariesLazy load, tree-shake, remove unused deps
Server componentsHeavy logic, data fetchingCache, split components, server actions
NavigationLag during route changesSuspense, cache, lightweight layouts
ImagesLCP & CLSnext/image, width/height, alt
ScriptsHydration blockingScript strategies (lazyOnload/afterInteractive)
MetricsLCP, INP, CLS, TBT, HydrationMonitor via useReportWebVitals and Lighthouse