# Next.js Performance: Optimizing Images, Fonts & Core Web Vitals
Last month, I ran into a problem that cost us two days at Beyin. A client in Abu Dhabi complained their Next.js e-commerce site was painfully slow. Lighthouse gave us a 45 on performance. The culprit? Unoptimized images and fonts. Here's what I learned.
Why This Matters (and Why I Care)
Core Web Vitals aren't just Google metrics—they directly impact your bottom line. In our project, fixing LCP (Largest Contentful Paint) from 4.2s to 1.8s boosted conversions by 22%. I've seen too many devs ignore `next/image` and load fonts synchronously. That's amateur hour. With **web performance 2025** standards getting tighter, you can't afford to skip this.
The Basics You Actually Need
Start with `next/image`—it's the single biggest win for **nextjs optimization**:
// app/components/OptimizedHero.tsx
import Image from 'next/image'
export default function Hero() {
return (
<Image
src="/hero.webp" // Always use WebP/AVIF
alt="Hero banner"
width={1200}
height={600}
priority // Only for above-fold images
className="rounded-lg"
/>
)
}
For fonts, use `next/font` to avoid layout shift:
// app/layout.tsx
import { Inter } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
display: 'swap', // Critical for CLS
})
How I Build With It (Step by Step)
1. **Configure next.config.js** for automatic image optimization:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 1080, 1200],
},
}
export default nextConfig
2. **Lazy load below-fold images**—Next.js does this by default with `loading="lazy"`.
3. **Preload critical fonts** in `<head>`:
// app/layout.tsx
export default function RootLayout({ children }) {
return (
<html>
<head>
<link rel="preload" href="/fonts/inter.woff2" as="font" crossOrigin="anonymous" />
</head>
<body>{children}</body>
</html>
)
}
Mistakes I Made (So You Don't Have To)
Advanced Tips From Production
My Honest Take
**Next.js performance** isn't rocket science—it's discipline. Use `next/image`, `next/font`, and measure with Lighthouse. Most tutorials overcomplicate it. I've shipped 12+ production apps this way, and it works. Start with images, then fonts, then measure. You'll hit 90+ Lighthouse in an afternoon.
---
*Mohamed Qurashi | Full-Stack Developer at Beyin Digital | [https://qurashi.dev](https://qurashi.dev)*
---
**Further reading:**
**Related articles on this blog:**