Images & fonts
Two components that save most of your load time
next/image handles size, format and timing for images. next/font ships fonts at build time. Both are little effort for a lot of effect.
When a page is slow it is rarely the JavaScript. Usually it is oversized images and fonts fetched at runtime. Next.js ships a ready-made answer for both.
Images
import Image from "next/image";
import hero from "./hero.jpg";
// Imported image: Next.js knows the dimensions itself
<Image src={hero} alt="View across Berlin" priority />
// From the web: give the size, otherwise the layout jumps
<Image
src="https://cdn.example.com/photo.jpg"
alt="Product photo"
width={800}
height={600}
/> next/imageThe image component that handles size, format and loading behaviour for you – and saves most of the load time.→ automatically serves a modern format, scales to the size actually needed, and only loads once the image comes near the visible area.
Without alt the image is invisible to screen readers – and Next.js rightly complains. Without width and height the browser does not know how much room to reserve, and the page jumps when the image arrives. With imported images that takes care of itself.
// The big image at the top: load it now, not lazily
<Image src={hero} alt="…" priority />
// Everything else: the default, i.e. lazy – exactly right Images from other domains only work after an entry in next.config.js under images.remotePatterns. That stops your site from becoming a free image service for strangers.
Fonts
import { Inter } from "next/font/google";
const inter = Inter({
subsets: ["latin"],
display: "swap",
variable: "--font-inter",
});
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.variable}>
<body>{children}</body>
</html>
);
} next/fontDownloads fonts at build time and puts them next to your code – no request to Google, no jumping text.→ downloads the font at build time and puts it next to your code. At runtime there is no request to Google – that saves a connection and spares you the data-protection discussion along with it.
<link
href="https://fonts.googleapis.com/css2?family=Inter"
rel="stylesheet"
/> import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] }); Side effect: Next.js computes a matching fallback for the time before the font arrives, so the text does not jump when it swaps.
import localFont from "next/font/local";
const brand = localFont({
src: [
{ path: "./Brand-Regular.woff2", weight: "400" },
{ path: "./Brand-Bold.woff2", weight: "700" },
],
variable: "--font-brand",
}); What it buys you
- +
next/imagefor anything that is a photograph - +
priorityfor the one big image at the top of the page - +
next/fontfor every font – including your own files
- −
<img>for photos – that throws away format, size and timing - −
priorityeverywhere: then nothing is prioritised again - −
Fetching fonts from the web with a
<link>
A 2 KB SVG icon gains nothing from image optimisation – <img> or the SVG inline is simpler there. next/image pays off for photographs, not vector graphics.
Does it stick?
4 questions on this lesson. Wrong answers show up in your stats.