next/image: img with the footguns removed
A plain <img> can silently wreck a page: huge files sent to phones, and content jumping as images pop in (layout shift). Next.js ships a component that fixes both:
import Image from "next/image"; <Image src="/team.jpg" alt="Our team" width={800} height={500} />
What it does for you:
- Resizes and re-encodes to modern formats per device, so a phone never downloads a desktop-size JPEG.
- Lazy-loads images below the fold by default.
- Reserves space from
widthandheightbefore loading, so the layout never jumps.
That is also why width, height, and alt are required: the first two prevent layout shift, and alt you know from accessibility basics.
Why width and height are required
next/image insists on width and height for a local image so it can reserve the right space before the image loads, which is what prevents layout shift.
Knowing the aspect ratio up front lets Next.js render a correctly-sized placeholder box. Surrounding content is laid out around that box immediately, so nothing jumps when the real pixels arrive a moment later.
These props are a layout-stability contract, not a crop or a hard display size. The image can still be sized responsively with CSS. What Next.js needs is the ratio, so it can hold the right amount of room.
next/font: fonts without the flash
Loading Google Fonts with a <link> tag costs an extra round trip to Google and often a flash of fallback text. next/font downloads the font at build time and self-hosts it:
// app/layout.js import { Inter } from "next/font/google"; const inter = Inter({ subsets: ["latin"] }); export default function RootLayout({ children }) { return ( <html lang="en" className={inter.className}> <body>{children}</body> </html> ); }
No request ever goes to Google from your users' browsers (better privacy and speed), and the generated CSS includes fallback metrics that minimize text reflow. Set it once in the root layout and forget it.
Fixing a jumpy 4 MB hero photo
Here is a two-symptom bug: a teammate's hero photo makes the headline jump down half a second after page load, and mobile users download a 4 MB file. One component fixes both, the Image component from next/image.
Why it works out that way
- The required
widthandheightlet it reserve space up front, so the headline never gets shoved down once the image arrives. That is the layout-shift half. - Its automatic resizing and format conversion serve mobile users an appropriately small file instead of the original 4 MB photo. That is the bandwidth half.
- Both problems are exactly what the built-in image component exists to solve, which is why reaching for a plain
imgtag in Next.js is usually a mistake worth flagging in review.
| Symptom | Plain img | next/image |
|---|---|---|
| File size on mobile | Original, 4 MB | Resized and re-encoded |
| Space reserved before load | No | Yes, from width/height |
| Below-the-fold loading | Eager by default | Lazy by default |
alt text | Optional, often forgotten | Required |