Skip to main content

Images and Fonts

A common reason for terrible web performance scores (like Google Lighthouse) revolves around massive, unoptimized images causing Cumulative Layout Shifts (CLS) and custom web fonts causing text flickering.

Next.js provides native components to permanently solve both of these frontend issues out of the box.

The <Image /> Component

Standard HTML <img> tags load synchronously and can aggressively jump the layout down the screen once the massive image data finally finishes injecting into the browser DOM.

The Next.js <Image> component replaces standard tags and provides three automatic benefits:

  1. Size Optimization: Automatically converts images into modern WebP or AVIF formats for smaller file sizes.
  2. Lazy Loading: Images off-screen are not downloaded until the user scrolls near them natively.
  3. Layout Shift Prevention: Hardcoding width and height reserves space on the screen before the image loads.
import Image from 'next/image';
import profilePic from '../public/me.png';

export default function Profile() {
return (
<Image
src={profilePic}
alt="Profile Picture"
placeholder="blur" // Adds a tiny blurred placeholder while downloading
width={500}
height={500}
/>
);
}

next/font

Custom Google Fonts usually require establishing external network connections to Google servers during the page load, causing text to briefly appear invisible (FOIT) or jump sizes.

next/font automatically pulls the font files securely into your project during the next build phase instead. It hosts the fonts locally on your server permanently, totally eliminating external network round trips.

import { Inter } from 'next/font/google';

// Configures the font subset to keep bundle sizes lean
const inter = Inter({ subsets: ['latin'] });

export default function RootLayout({ children }) {
return (
<html lang="en">
{/* Applies the compiled font class globally into the body tag */}
<body className={inter.className}>{children}</body>
</html>
);
}