Lesson 27 +10 XP

Image & Font Optimization (next/image, next/font)

Image & Font Optimization (next/image, next/font)

Next.js provides built-in components to automatically optimize media assets and typography, maximizing performance scores on Google Lighthouse.

1. Image Optimization (next/image)

The next/image component extends the HTML <img> tag with automatic image optimization:

  • Resizing: Serves appropriately sized images for different devices.
  • Modern Formats: Automatically converts PNG/JPEG images into modern WebP or AVIF formats.
  • Layout Shift Prevention: Eliminates Cumulative Layout Shift (CLS) automatically.
  • Lazy Loading: Images load only when entering the user viewport.
import Image from 'next/image';
import avatarPic from '@/public/avatar.jpg';

export default function UserCard() {
  return (
    <div className="p-4 border rounded">
      {/* 1. Static Import (Width/Height inferred automatically) */}
      <Image
        src={avatarPic}
        alt="User Profile Avatar"
        placeholder="blur" // Blurred placeholder during loading!
        className="rounded-full"
      />

      {/* 2. Remote Image URL (Explicit width/height required) */}
      <Image
        src="https://images.unsplash.com/photo-1570295999919-56ceb5ecca61"
        alt="External Unsplash User"
        width={100}
        height={100}
        priority // Load eagerly if above the fold!
      />
    </div>
  );
}
⚠️ DocHero Safety Disclaimer

Remote image URLs must be declared in next.config.mjs under images.remotePatterns.

2. Font Optimization (next/font)

next/font automatically optimizes web fonts (including Google Fonts and local font files) by downloading font assets at build time and hosting them alongside your static CSS.

Benefits of next/font:

  • Zero external network requests to Google Fonts servers at runtime.
  • Zero layout shift thanks to automatic size-adjust CSS fallbacks.
// app/layout.tsx
import { Inter, Roboto_Mono } from 'next/font/google';

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-inter',
});

const robotoMono = Roboto_Mono({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-roboto-mono',
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={`${inter.variable} ${robotoMono.variable}`}>
      <body className={inter.className}>{children}</body>
    </html>
  );
}

Optimization Features Reference

Component / UtilityKey FeatureBenefit
<Image placeholder="blur" />Shows blurred image previewPrevents layout pop-in during slow loads
<Image priority />Disables lazy loading for Hero imageImproves Largest Contentful Paint (LCP)
next/font/googleSelf-hosts Google FontsEliminates external font DNS lookups
next/font/localSelf-hosts custom font filesZero-CLS custom font rendering

TL;DR

  • Always use <Image /> from next/cache or next/image instead of plain <img> tags.
  • Declare external image domain patterns in next.config.mjs.
  • next/font downloads Google Fonts at build time to serve them locally with zero CLS.
  • Use priority on above-the-fold images to optimize LCP score.