Loading...
A slow website kills conversions long before it kills rankings. Here are the ten optimizations that move the needle most, in the order we apply them.
A PageSpeed score in the 40s is almost never one big problem, it's a stack of smaller ones: unoptimized images, render-blocking scripts, third-party tags, and a font loading strategy nobody thought about. Getting to a near-perfect score is a matter of working through that stack in the right order, since some fixes unlock the value of others.
Here are the ten optimizations that move Core Web Vitals and PageSpeed scores the most, ranked roughly by impact, along with the trade-off each one involves.
Unoptimized images are the single most common cause of a poor Largest Contentful Paint (LCP) score, since the hero image is usually the largest content element on the page. Converting to WebP or AVIF, serving responsive sizes via `srcset`, and using Next.js's built-in `<Image>` component (which handles resizing, format negotiation, and lazy loading automatically) typically produces the single biggest score jump of any change on this list.
Trade-off: AVIF compresses better than WebP but encodes more slowly at build time; for large image libraries, WebP is often the better default unless every last kilobyte matters.
CSS and synchronous JavaScript in the `<head>` block the browser from painting anything until they finish downloading and executing. Inlining critical above-the-fold CSS and deferring everything else, and adding `async` or `defer` to non-critical scripts, lets the browser paint content immediately instead of waiting.
Trade-off: aggressive CSS splitting can introduce a brief flash of unstyled content if not handled carefully; test on a throttled connection, not just fast Wi-Fi, before shipping.
Analytics tags, chat widgets, ad pixels, and marketing scripts are consistently the most underestimated performance cost on a site, because each one is added independently by a different team member with no visibility into the cumulative effect. It's common to find five or six third-party scripts each adding a few hundred milliseconds, none of which look significant alone.
Audit every third-party script with Chrome DevTools' network panel, load anything non-critical with `next/script`'s `lazyOnload` strategy, and remove scripts nobody can justify keeping. This single audit often recovers more speed than any code-level optimization on the page itself.
Web fonts that block rendering until they download cause both a slow First Contentful Paint and layout shift when the fallback font swaps to the real one. `next/font` solves most of this automatically by self-hosting Google Fonts and eliminating the external request entirely, while `font-display: swap` prevents invisible text during the font swap.
Trade-off: self-hosting fonts increases your own server's asset payload slightly, but removes a third-party DNS lookup and connection, which is almost always the better trade for Core Web Vitals.
Shipping the entire application bundle on every route means users pay the download and parse cost for code they may never use on that page. Next.js code-splits by route automatically, but component-level splitting (via `dynamic()` imports for heavy, below-the-fold components like modals, charts, or rich editors) cuts the initial bundle further.
Run the bundle analyzer periodically, it's common to find an entire charting or date-picker library shipped on every page when only one route actually uses it.
Layout shift usually comes from images and ads without explicit dimensions, web fonts swapping in late, or dynamically injected content (like a cookie banner) pushing the page around after it has already rendered. Setting explicit `width` and `height` on every image and reserving space for dynamically loaded elements eliminates most CLS issues.
This is one of the cheapest fixes on this list in terms of engineering effort, and one of the most visible to users, since layout shift is the kind of thing people notice even without knowing the technical term for it.
Serving static assets without proper cache headers means returning visitors re-download everything on every visit. Setting long `Cache-Control` headers on immutable assets (anything with a content hash in the filename, which Next.js does by default for its build output) and serving everything through a CDN edge network dramatically cuts repeat-visit load times.
Trade-off: aggressive caching on non-hashed assets (like an unversioned logo file) can serve stale content after an update; only cache aggressively what's safe to cache aggressively.
Every other optimization is capped by how fast the server responds in the first place. Slow database queries, uncached API calls, and cold-start serverless functions all show up as a poor Time to First Byte. Static generation or Incremental Static Regeneration for any page that doesn't need to be fully dynamic removes this bottleneck entirely for that route.
For pages that must be dynamic, adding a caching layer (Redis, or Next.js's built-in data cache) in front of slow queries is usually the highest-leverage fix.
Interaction to Next Paint (INP), which replaced First Input Delay as a Core Web Vital, measures how responsive the page feels when a user actually clicks or taps something. Heavy JavaScript execution on the main thread, large state updates, unoptimized re-renders, expensive synchronous computations, delays that response even after the page has visually loaded.
Breaking up long tasks, memoizing expensive computations, and moving genuinely heavy work off the main thread (a Web Worker, for the rare case that justifies it) keeps the page feeling responsive under real interaction, not just fast in a synthetic load test.
Large, unpurged CSS frameworks and design systems often ship far more CSS than a given page actually uses. Tailwind CSS handles this well by default since it only generates the utility classes actually referenced in your code, but hand-written or legacy CSS files frequently carry years of accumulated, unused rules that still cost parse time on every page load.
Running an unused-CSS audit (Chrome DevTools' Coverage tab) periodically catches this drift before it becomes a meaningful chunk of the page weight.
PageSpeed Insights reports both a lab score (a controlled, simulated test) and, once a site has enough traffic, field data from the Chrome User Experience Report (real visitors, on real devices and networks). The lab score is useful for iterating quickly during development, but the field data is what Google actually uses as a ranking input, and the two can diverge meaningfully, especially for sites with a lot of mobile traffic on slower connections.
Track both, but treat field data as the source of truth. It's common to fix a site to a near-perfect lab score while a large share of real users, often on older phones or throttled mobile data, still experience it as slow. Testing on an actual mid-range phone with network throttling enabled catches this gap before real users do.
None of these ten optimizations are exotic. What separates a site stuck in the 40s from one scoring in the high 90s is usually just working through this list methodically, images and render-blocking resources first, since they have the largest impact, then the rest in whatever order the site's specific audit reveals matters most.
StrattonX Technologies includes a full performance pass, covering every item on this list, as part of every website build, and offers standalone performance audits for existing sites. If your PageSpeed score is holding your conversions back, our web development services team can show you exactly where the weight is coming from.
Book a free consultation and lets build something extraordinary together.