Skip to content

Speed Is a Ranking Factor: The Next.js Performance Checklist by Business Size

Google measures your speed with real users and ranks you on it. Next.js hands you the tools to win. Most sites leave them switched off.

John Cravey with EleviFounder10 min read

Site speed is not a vanity metric. Google measures it with your real visitors — the Core Web Vitals — and uses it as a ranking signal, and every extra second of load time quietly bleeds conversions on top of that. The good news for anyone on Next.js is that the framework ships the hard parts of performance as built-in primitives: image optimization, font optimization, code splitting, streaming. The bad news is that they don’t all switch themselves on, and the most common thing we find in a slow Next.js site is a team that hand-rolled the exact things the framework would have done better. Here’s the checklist that makes a site fast enough to rank, and how to apply it at your size. If you want the why behind the numbers, start with why slow websites are killing your SEO.

The three metrics Google actually grades

  • LCP (Largest Contentful Paint) — how long until the biggest thing on screen renders. Target under 2.5s. Usually your hero image or headline.
  • INP (Interaction to Next Paint) — the worst delay between a user action and the screen responding. Target under 200ms. This is where too much client-side JavaScript hurts you.
  • CLS (Cumulative Layout Shift) — how much the page jumps around while loading. Target under 0.1. Usually caused by images and ads without reserved space.

These are measured on real users at the 75th percentile over 28 days, which is why a fast lab score doesn’t guarantee a passing grade — your actual visitors on real phones and networks are the graders. Next.js primitives target all three.

next/image: the single biggest LCP win

Images are almost always the largest asset on a page and the most common cause of a failing LCP. The `next/image` component fixes this automatically: it serves modern formats (AVIF/WebP), generates responsive sizes so a phone doesn’t download a desktop-sized image, lazy-loads what’s below the fold, and reserves layout space so images don’t cause CLS. The one rule people miss: mark your above-the-fold hero image with `priority` so it loads immediately instead of being lazy-loaded.

import Image from "next/image";

// Hero — load it now, it's the LCP element
<Image src="/hero.jpg" alt="…" width={1600} height={900} priority />

// Below the fold — lazy by default, no priority needed
<Image src="/gallery-3.jpg" alt="…" width={800} height={600} />

next/font: kill the layout shift and the third-party request

Web fonts cause two problems: a request to Google’s font servers on every load (slow, and a privacy flag in some regions), and a flash of unstyled or invisible text that counts as layout shift. `next/font` solves both by self-hosting the font at build time and reserving its space, so there’s no third-party round-trip and no shift.

// app/layout.tsx
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"], display: "swap" });

export default function RootLayout({ children }) {
  return <html className={inter.className}><body>{children}</body></html>;
}

Lazy load the heavy, non-critical JavaScript

A charting library, a video embed, a map, an animation library — these are big, and most of them aren’t needed for the first paint. Next’s dynamic import loads them only when they’re actually reached, keeping your initial bundle small and your INP fast. The related discipline is not marking whole trees as client components when they don’t need to be — a topic we cover in server vs client components.

import dynamic from "next/dynamic";

// Only ships the chart JS when this component renders
const RevenueChart = dynamic(() => import("./RevenueChart"), {
  loading: () => <ChartSkeleton />,
});

Streaming: render the fast parts first

You don’t have to make the whole page wait for the slowest data. Wrap a slow section in a `<Suspense>` boundary and Next streams the rest of the page immediately, filling in the slow part when it’s ready. Your LCP fires on the fast content instead of waiting for the report that takes 800ms to query. This is a rendering-mode decision as much as a performance one — see picking the right rendering mode.

The production checklist before you ship

  1. Every image uses next/image; the hero has priority; nothing is a raw <img>.
  2. Fonts load through next/font, not a <link> to a font CDN.
  3. Heavy, below-the-fold components are dynamically imported.
  4. Slow data is behind a Suspense boundary so the shell streams first.
  5. You’ve run the real build (not just dev) and checked the per-route JS payloads Next prints.
  6. You’ve confirmed the numbers on a mid-range phone on a throttled network — not just your laptop.

A worked example: fixing a failing LCP

Here’s the most common performance audit we run, start to finish. A site fails LCP at 4.1s on mobile. We open the page and the largest element is a full-width hero photo shipped as a 2.3MB JPEG through a plain `<img>` tag. Three changes: swap the `<img>` for `next/image` with `priority` set, which serves a right-sized AVIF instead of the giant JPEG and loads it immediately; move the two web fonts to `next/font` so text stops shifting; and dynamically import the testimonial carousel that was pulling an animation library into the initial bundle. LCP drops from 4.1s to 1.8s. No redesign, no new content, no lost functionality — just the framework’s primitives switched on where a hand-rolled version had switched them off. That’s the shape of most performance wins: not exotic, just the defaults applied. The web.dev guide to optimizing LCP is the definitive reference for the full checklist behind that one metric.

Third-party scripts: the performance you didn’t write

Often the slowest thing on a page is code you didn’t write — an analytics tag, a chat widget, a heat-mapping tool, an ad script. Each one is JavaScript that can block the main thread and wreck your INP. Next’s Script component lets you control when they load: `strategy="afterInteractive"` for things that can wait until the page is usable, `strategy="lazyOnload"` for things that can wait until everything else is done. Audit your third-party tags ruthlessly — most sites carry two or three they no longer use, each still costing every visitor load time. The rule we give clients: every third-party script has to justify its weight against the conversion it drives, and the ones that can’t get cut. Google’s Core Web Vitals overview on web.dev is worth reading in full for how these interactions get scored.

Reserve space for everything to kill layout shift

CLS — the metric that measures visual jumpiness — is almost always caused by content that loads without a reserved space, shoving everything below it down as it arrives. Images without dimensions, ads that pop in, fonts that swap, banners that appear after load. `next/image` reserves space from its width and height automatically, and `next/font` reserves the font’s space, which handles the two biggest causes for free. For anything else that loads late — an embed, a cookie banner, a promo bar — give it a fixed height container so the page doesn’t reflow when it arrives. It’s an unglamorous discipline, but a page that holds still while it loads feels dramatically more solid than one that dances, and Google grades you on the difference.

Mobile is the grade, not desktop

The single biggest reason teams are surprised by a failing Core Web Vitals score is that they test on the wrong device. Google indexes and grades your site mobile-first, and it measures real users — most of whom are on mid-range phones over imperfect networks, not the developer’s high-end laptop on office fiber. A hero image that loads instantly on your machine can take three seconds on a mid-tier Android on a weak connection, and that visitor’s experience is the one that counts toward your grade. So test the way you’re graded. Use the mobile throttling in your browser’s dev tools, and better, load your site on an actual mid-range phone on cellular data. The gap between that and your laptop is usually where your real LCP lives.

This is also why a single green Lighthouse run on your desktop is misleading comfort. Lighthouse is a lab test in ideal conditions; Google ranks on field data — your real users over a rolling 28-day window — which is why a site can score 95 in the lab and still fail its Core Web Vitals in Search Console. Pull the field data from the Core Web Vitals report and treat that as the source of truth, using lab runs only to catch a regression before it ships. When you frame performance as “what my median mobile visitor actually experiences” rather than “what my dev machine scores,” you start fixing the things that move the grade — the oversized hero, the render-blocking third-party tag, the font that swaps late — instead of chasing a lab number that was never the thing being measured. Speed is a promise you make to the person on the slow phone, and they’re the one Google is asking.

What this means for your business

The primitives are free. What changes with size is how you enforce them and where the biggest wins hide.

For agencies

Performance is a quality bar you can guarantee and a service you can sell. Bake a performance budget into your build process — a CI check that fails when a route’s JavaScript crosses a threshold — so no client site regresses silently between launches. The primitives (next/image, next/font, dynamic import) should be the default in your starter, not a per-project decision a junior dev might skip. And a “Core Web Vitals audit + fix” is one of the easiest paid engagements to sell to a prospect on any platform, because the before/after is measurable and the failing grade is right there in their Search Console. Speed is one of the few SEO claims you can prove in a week.

For micro businesses (1–5 people)

You won’t be tuning bundle budgets, and you don’t need to. The wins that matter for a small site are concrete: make sure your hero image goes through next/image with priority, your fonts use next/font, and you don’t have a giant unoptimized background image or an autoplaying video tanking your load. If your site was built on Next.js and feels slow, it’s almost always images. Run your homepage through PageSpeed Insights, look at the LCP number, and if it’s over 2.5s, that’s your one thing to fix. If it’s not obvious how, it’s a quick, scoped job for us.

For small businesses (SMEs)

You have enough pages and enough traffic that a passing Core Web Vitals grade is real money in rankings and conversions. Audit your templates, not every page — fix the shared header, hero, and product/service components once and the fix propagates. Watch the Core Web Vitals report in Search Console for the page groups Google flags as “needs improvement,” and prioritize the template behind the biggest group. The common culprit at your size is a component someone marked as client-rendered that pulled a heavy library into the bundle sitewide; find it and the whole site gets faster at once.

For mid-size companies

Performance at your scale is an governance and monitoring problem. Set an enforced performance budget in CI, run real-user monitoring so you see the field data your customers actually experience, and treat a Core Web Vitals regression as a tracked incident, because at your traffic a tenth of a second is measurable revenue. The subtle failures here are the ones CI misses — a page that re-renders too often, an animation that janks on scroll, a third-party tag that blocks interaction. Budget for real-device testing and a standing performance owner. The framework gives your teams the primitives; your job is to make sure a hundred developers can’t accidentally switch them off.

How we run this at Frontend Horizon

Every FH site ships with next/image and next/font as defaults, heavy components lazy-loaded, slow data streamed behind Suspense, and a performance posture we verify on real devices before launch — not just a green lab score. Speed is part of the build, not a cleanup pass. If your site is slow and you can’t tell why, or your Core Web Vitals are failing, run a free discovery and we’ll show you exactly what’s costing you the milliseconds. Keep reading: the metadata playbook and structured data cover the on-page SEO that a fast site lets shine.

Written by
John Cravey
Founder

Founder of Frontend Horizon. Writes most of the long-form work on the FH blog.

Newer post
AI Search for Micro Businesses: The Smallest Setup That Gets You Cited by Answer Engines
Older post
AI Search for Small and Growing Teams: Semantic and Hybrid Search on Supabase Without a Data Team
Keep reading

More from the blog

SEO·10 min

Automated Technical SEO Audits: Crawl, Score, and Fix With AI

A once-a-year audit finds problems a year too late. The point of automating it is that it never stops looking.

Performance·4 min

Core Web Vitals 2026: The Metrics That Matter and the Targets That Hold

Three numbers. Hit them and you’re competing on content; miss them and you’re competing one hand tied.

Next.js·11 min

Titles, Meta Descriptions, and Social Cards: The Next.js Metadata Playbook for Every Business Size

Your title tag is the ad you never wrote. Here’s how to make Next.js render one that gets clicked, whatever size you are.