Start here: how to diagnose your website speed
Before you fix anything, measure. Open Chrome, navigate to your website, press F12 to open DevTools, click the Lighthouse tab, select Performance and Mobile mode, then click Analyze. Lighthouse gives you a score from 0–100 and flags the specific issues costing you points — it is free, takes 30 seconds, and is the same tool Google uses to evaluate Core Web Vitals.
Alternatively, go to pagespeed.web.dev and enter your URL for the same test without needing DevTools. A score below 50 is Poor; 50–89 is Needs Improvement; 90+ is Good. Users bounce at a measurably higher rate when pages take more than 3 seconds to load, so a low Lighthouse score has a direct impact on conversions and search rankings.
Cause 1: Unoptimized images
Images account for the majority of page weight on most websites. Serving large JPEGs or PNGs at their original resolution and format is the single most common cause of slow load times. A real estate listing page with 10 full-resolution property photos can easily load 8–15 MB of images. The same photos as properly sized WebPs would be under 600 KB — a 20× difference from one change.
The fix: convert all images to WebP (30–50% smaller than JPEG at equal quality), serve them at the size they actually display (a 300px thumbnail doesn't need a 2000px source), add lazy loading for images below the fold, and use a CDN to serve them from a server geographically close to the user.
- Convert images to WebP — 30–50% smaller than JPEG at equal quality.
- Serve images at display size, not original resolution.
- Add loading="lazy" to all images below the fold.
- Use a CDN (Cloudflare free tier, Vercel's built-in CDN) for fast global delivery.
Cause 2: Cheap or wrong hosting
TTFB (Time to First Byte) measures how long your server takes to respond to a request. On cheap shared hosting, TTFB is often 1–3 seconds before the page even begins loading. The Lighthouse target is under 600ms; under 200ms is ideal.
Shared hosting puts hundreds of websites on one server. When another site gets a traffic spike, your TTFB suffers. The fix is faster infrastructure: a VPS, a managed platform like Vercel, Netlify, or Railway, or a CDN-fronted static deployment. For a Next.js site, Vercel is zero-config and free for most projects.
Cause 3: Too much JavaScript, or JavaScript in the wrong place
JavaScript blocks rendering. Script tags in the page <head> without defer or async attributes force the browser to pause rendering until the script downloads and executes. A WordPress site with 15 plugins — each adding its own JS file — commonly has 500 KB–2 MB of render-blocking scripts.
The fix is to add defer or async to non-critical script tags, or to eliminate the scripts entirely. Modern frameworks like Next.js handle this automatically through code-splitting and deferred hydration. On a legacy site, manually auditing every plugin's JavaScript impact is time-consuming — this is one of the main reasons a rebuild on a modern framework is sometimes cheaper than patching.
Cause 4: No content delivery network (CDN)
If your server is in London and a visitor is in Dubai, every asset they request must travel that distance. A CDN solves this by caching assets on servers worldwide so users get files from the nearest location. The round-trip from Dubai to London is roughly 120ms; from Dubai to a CDN node in the UAE it is under 10ms — that difference compounds across every asset on the page.
Cloudflare's free tier is the easiest CDN to add — you change your domain's nameservers and Cloudflare caches static assets automatically. For Next.js on Vercel, CDN is built in across 100+ edge locations at no extra cost.
Cause 5: Missing or broken caching
Without proper cache headers, browsers re-download every asset on every visit. Static assets — images, fonts, CSS, JavaScript — should be cached aggressively with a Cache-Control header of max-age=31536000 (one year) combined with versioned filenames, so browsers only fetch them when they genuinely change. Dynamic HTML should use shorter or no caching.
Modern frameworks (Next.js, Astro) handle asset cache headers correctly by default. Older WordPress or custom PHP sites often serve assets with no caching at all — meaning a returning visitor loads the entire page from scratch every time.
When to patch it vs. when to rebuild
Targeted fixes work when Lighthouse identifies 2–4 specific problems — image compression, a slow third-party widget, deferred scripts. You can address those in a day or two without touching the underlying platform.
A rebuild is usually more cost-effective when the Lighthouse score is consistently below 50 on a WordPress or legacy site, because the cause is architectural: a framework not designed for performance, a plugin ecosystem with compounding dependencies, or a template not built for speed. A rebuild on Next.js typically delivers a 40–60 point Lighthouse improvement and pays for itself through better conversion rates and search rankings within 6 months.