Which built-in Next.js features improve website performance?
The three built-in Next.js features that matter most for marketing sites are the Image component (next/image), the font module (next/font) and the Script component (next/script). Together they handle the heaviest things marketing teams add: large visuals, custom typefaces and third-party tags.
They're not magic, though. Each one has defaults that work for simple pages and settings you need to get right for real ones. This guide gives the defaults we use on every build. For the bigger question of whether code suits your team, see our guide to Next.js for a marketing website.
Feature | What it does | Metric it helps most | The setting people get wrong |
|---|---|---|---|
next/image | Resizes, converts to WebP or AVIF, lazy loads, reserves space | LCP and CLS | Missing or wrong sizes value |
next/font | Self-hosts fonts, preloads them, tunes fallback metrics | CLS and LCP | Loading too many weights |
next/script | Controls when and how external scripts load | INP and LCP | Loading every tag before the page is interactive |
Metadata API | Generates titles, Open Graph images and tags | None directly; helps SEO | Large dynamic OG images on every request |
How does Next.js image optimization work?
Next.js image optimization works by generating several sizes of each image on demand, serving the smallest one that fits the visitor's screen in a modern format, and caching the result. The Image component also lazy loads off-screen images and reserves their space so nothing jumps.
The key input is the sizes attribute. It tells the browser how wide the image will be at each breakpoint, so it can pick the right file. Without it, a full-width image is treated as full viewport width on every device, which is fine, but a card image in a three-column grid gets downloaded far larger than it displays. Remote images also need their domains listed in the config before they can be optimized.
- Use width and height, or fill with a sized parent. Both reserve space and stop layout shift.
- Write a real sizes value for any image narrower than the viewport, for example a card that's a third of the page on desktop and full width on mobile.
- Keep the default lazy loading for everything below the fold.
- Allow AVIF and WebP in the image config; the component picks what the browser supports.
- Compress sources before upload. Optimization helps, but a huge source file still slows the first transform.
How should you load the hero image?
Load the hero image eagerly with high fetch priority, because it's usually the Largest Contentful Paint element. On the Image component, that means setting the priority option on the hero only; recent versions also offer preload and fetchPriority settings, so check the docs for your version.
Prioritizing more than one or two images defeats the purpose, since they all compete for bandwidth. Also make sure the hero image is in the server-rendered HTML, not injected by a client component or a CSS background set after load, or the browser can't discover it early. Our Core Web Vitals platform fixes cover the full LCP checklist.
How does next/font prevent layout shift?
next/font prevents layout shift by self-hosting the font files with your site and generating a fallback font with adjusted metrics, so the page doesn't reflow when the custom font arrives. It works for Google Fonts and for local font files.
Self-hosting also removes the extra connection to a font provider, which helps the first paint. The main decisions are how many families and weights you load and which character subsets you need. A variable font that covers every weight in one file is usually lighter than four static weights. Load display fonts only where they're used, and apply fonts through CSS variables so a design system can reference them by name, as described in our guide to building a design system for a marketing site.
Which next/script strategy should each tag use?
Pick the latest strategy each script can tolerate. Most marketing tags don't need to run before the visitor can read and click, and loading them early is one of the main causes of slow interactions.
Strategy | When it loads | Use it for |
|---|---|---|
beforeInteractive | Before hydration, in the initial HTML | Rare: consent banners that must run first |
afterInteractive (default) | Right after hydration | Tag manager, core analytics |
lazyOnload | When the browser is idle | Chat widgets, heatmaps, social embeds |
worker (experimental) | In a web worker | Heavy scripts, after testing compatibility |
On interaction | When the visitor clicks a facade | Video embeds, chat, calendars |
The on-interaction pattern is worth highlighting: show a static placeholder for a chat bubble or a video, and load the real script only when someone clicks. It removes the cost entirely for the majority who never use it. Heavy tags are the biggest INP risk on Next.js sites, which we cover in improving INP on Next.js.
Hypothetical example: a homepage audit using only built-in features
For example, suppose a homepage has a large hero image set as a CSS background, four font weights loaded from a provider, and a tag manager plus a chat widget loaded in the head.
The fixes use only built-in features. The hero becomes an Image component with fill and priority. Fonts move to next/font with one variable file and a tuned fallback. The tag manager loads afterInteractive, and the chat widget becomes a click-to-load facade. No redesign is needed, and each change is measurable in field data over the following weeks.
What about video, SVG and other heavy assets?
Video and SVG sit outside next/image, so they need their own rules. Treat a hero video as an enhancement on top of a fast poster image, and keep SVGs small and inline only when they're simple.
- Hero video: set a poster image, use preload none or metadata, compress to a short loop, and consider showing only the poster on mobile.
- Embedded video: use a lightweight facade and load the player on click.
- SVG icons: inline small icons; serve large illustrations as files so they cache.
- Lottie and animation files: load them after the first paint and pause them off-screen.
If you host on Cloudflare, check how image optimization is configured, since it may need a custom loader or the host's own image service; our guide to hosting Next.js on Cloudflare Workers explains the options. Teams moving from a builder often see the biggest gains here, as covered in our Wix to Next.js migration guide.
