Next.js App Router Performance Optimization: Deep Dive
The React Server Component (RSC) paradigm in the Next.js App Router changes how we structure web apps by keeping client bundles lean and streaming rendered HTML directly from the server edge.
Here is a blueprint for achieving sub-second Largest Contentful Paint (LCP) and rock-solid Interaction to Next Paint (INP).
1. Zero-JS Server Components by Default
Always keep components on the server unless you explicitly need interactivity (event listeners, hooks like useState, useEffect, or browser APIs).
// app/components/StatsCard.tsx
// This component ships ZERO JavaScript to the browser client!
export default async function StatsCard({ metric, value }: { metric: string; value: number }) {
return (
<div className="p-6 rounded-lg bg-navy-light border border-slate-dark/30">
<p className="text-slate text-sm font-mono">{metric}</p>
<h3 className="text-3xl font-bold text-teal-accent mt-2">{value.toLocaleString()}</h3>
</div>
);
}
2. Dynamic Imports for Heavy Interactive Widgets
If you have heavyweight components like 3D canvases, interactive code editors, or rich data tables, load them lazily with next/dynamic:
import dynamic from "next/dynamic";
const MarkdownCanvasEditor = dynamic(() => import("@/components/admin/MarkdownCanvas"), {
ssr: false,
loading: () => <div className="h-64 animate-pulse bg-navy-light rounded-md" />
});
3. Streaming and Suspense Boundaries
Break your UI into independent suspense chunks so fast components render immediately while slower data queries stream progressively:
import { Suspense } from "react";
import ProjectList from "@/components/ProjectList";
import ProjectSkeleton from "@/components/ProjectSkeleton";
export default function WorkPage() {
return (
<section>
<h2 className="text-2xl font-bold text-slate-lightest">Featured Work</h2>
<Suspense fallback={<ProjectSkeleton />}>
<ProjectList />
</Suspense>
</section>
);
}
Summary Checklist
| Optimization Technique | Target Impact | Primary Metric |
|---|---|---|
| Server Component Streaming | Fast initial HTML delivery | TTFB / FCP |
next/image with WebP/AVIF | Optimized visual assets | LCP |
Dynamic Imports (next/dynamic) | Reduced initial JS payload | INP |
Font Preloading (next/font) | Zero layout shift | CLS |