Hirefullstack – Software Engineering & IT-Beratung aus Berlin
← Back to overview
Beginner 9 min read

Images & fonts

Two components that save most of your load time

In one sentence

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

image.tsx
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.

Pitfall alt and size are not optional

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.

priority.tsx
// 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
Set priority exactly once per page: for the image visible without scrolling.
Good to know Third-party addresses have to be allowed

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

app/layout.tsx
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.

font is fetched at runtime
<link
  href="https://fonts.googleapis.com/css2?family=Inter"
  rel="stylesheet"
/>
font sits next to your code
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.

custom-font.ts
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

Reach for it when …
  • +

    next/image for anything that is a photograph

  • +

    priority for the one big image at the top of the page

  • +

    next/font for every font – including your own files

Skip it when …
  • <img> for photos – that throws away format, size and timing

  • priority everywhere: then nothing is prioritised again

  • Fetching fonts from the web with a <link>

Tip For icons a plain img is fine

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.

Hirefullstack

Need React firepower on your team?

We have been building React and Next.js applications for clients across Germany for years – as a single expert, as reinforcement for an existing team, or as a complete Scrum team.

Talk about your project →