How to Improve Core Web Vitals in Next.js Websites
Fix LCP, CLS, and INP in Next.js apps. Image and font optimization, JavaScript reduction, lazy loading, and testing tools for better search rankings and user experience.
What Core Web Vitals are
Core Web Vitals are Google's three key metrics for user experience: Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP). They directly affect search rankings and user perception of your site. For developer portfolios and Web3 landing pages, passing these metrics means faster loads, lower bounce rates, and better SEO.
LCP: Largest Contentful Paint
LCP measures how long the largest visible element takes to render. Target: under 2.5 seconds.
Common LCP elements: hero images, large text blocks, background images. Fix slow LCP by optimizing images, preloading critical assets, and using server-side rendering.
// Optimize hero images with next/image
import Image from 'next/image';
export function Hero() {
return (
<Image
src="/hero-dashboard.png"
alt="DeFi Dashboard Preview"
width={1200}
height={630}
priority
className="rounded-2xl"
/>
);
}// Preload critical fonts
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
preload: true,
});Avoid large background images loaded via CSS. Use next/image or optimize with WebP/AVIF formats.
CLS: Cumulative Layout Shift
CLS measures unexpected layout movement. Target: under 0.1.
Common causes: images without dimensions, fonts loading late, dynamically injected content (ads, banners), charts rendering without fixed containers.
// Fixed chart container prevents CLS
<div className="h-[300px] w-full">
{isLoading ? <ChartSkeleton /> : <PriceChart data={data} />}
</div>
// Skeleton matching final dimensions
function BalanceSkeleton() {
return (
<div className="h-[120px] rounded-xl border border-white/10 p-6">
<div className="h-4 w-24 animate-pulse rounded bg-white/5" />
<div className="mt-3 h-8 w-40 animate-pulse rounded bg-white/5" />
</div>
);
}INP: Interaction to Next Paint
INP measures responsiveness to user interactions (clicks, taps, key presses). Target: under 200ms.
Common causes: heavy JavaScript on the main thread, large React re-renders, unoptimized event handlers, third-party scripts blocking the main thread.
// Defer non-critical JavaScript
import dynamic from 'next/dynamic';
const Analytics = dynamic(() => import('@/components/Analytics'), { ssr: false });
const ChatWidget = dynamic(() => import('@/components/ChatWidget'), { ssr: false });Split large components to reduce re-render scope. Use startTransition for non-urgent state updates.
Image optimization
import Image from 'next/image';
<Image
src="/project-screenshot.png"
alt="Project screenshot"
width={800}
height={450}
sizes="(max-width: 768px) 100vw, 50vw"
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>Font optimization
import { Inter, JetBrains_Mono } from 'next/font/google';
const inter = Inter({ subsets: ['latin'], variable: '--font-inter' });
const mono = JetBrains_Mono({ subsets: ['latin'], variable: '--font-mono' });
// app/layout.tsx
<html className={`${inter.variable} ${mono.variable}`}>Self-hosted fonts via next/font eliminate render-blocking external font requests.
Reducing JavaScript
Lazy-load chart libraries and heavy components. Analyze bundle with @next/bundle-analyzer. Remove unused dependencies. Use Server Components for static content.
Testing tools
**Lighthouse** — built into Chrome DevTools. Run on every key page before shipping.
**Vercel Speed Insights** — real-user Core Web Vitals in production.
**web-vitals library** — programmatic measurement in your app.
// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next';
export default function Layout({ children }) {
return (
<html>
<body>
{children}
<SpeedInsights />
</body>
</html>
);
}FAQ
**What scores should I target?** LCP < 2.5s, CLS < 0.1, INP < 200ms. All three in the "Good" range.
**Do Web3 dashboards need good Core Web Vitals?** Yes, especially landing pages and public protocol pages. Wallet-connected dashboard views matter less for SEO but still affect user experience.
**How do charts affect CLS?** Charts rendering into empty containers cause layout shift. Always use fixed-height containers with skeleton placeholders.
**Should I optimize for mobile or desktop first?** Mobile. Google uses mobile-first indexing. Mobile Core Web Vitals are what affects rankings.
Want to work together? I build Web3 dashboards and DeFi interfaces.