Website Performance & Speed

A fast website isn't just a nice-to-have — it directly affects your search rankings, conversion rates, and how users feel about your brand. This guide covers everything you need to know.

Why Speed Matters

Site speed has measurable, direct impact on business outcomes:

  • SEO: Google uses Core Web Vitals as ranking signals. Slow sites rank lower, full stop.
  • Conversions: Amazon found every 100ms of latency cost them 1% in sales. Walmart reported a 2% increase in conversions for every 1 second improvement in load time.
  • Bounce rate: 53% of mobile users abandon a site that takes more than 3 seconds to load (Google data).
  • User perception: A slow site signals a low-quality or untrustworthy business, regardless of how good the design looks.

The target: your site should feel instant. Aim for a First Contentful Paint under 1.8 seconds and a PageSpeed Insights score of 90+ on mobile.

Core Web Vitals Explained

Core Web Vitals are the three performance metrics Google uses to measure page experience. They appear in PageSpeed Insights and Google Search Console.

LCP — Largest Contentful Paint

Measures how long it takes for the largest visible content element (usually a hero image or main heading) to fully load and appear on screen. This is the metric that most closely represents "when does the page feel loaded?"

  • Good: under 2.5 seconds
  • Needs improvement: 2.5–4 seconds
  • Poor: over 4 seconds

Common causes of slow LCP: Large unoptimised hero images, slow server response time, render-blocking JavaScript, and CSS that prevents images from loading.

INP — Interaction to Next Paint (replaced FID)

Measures the responsiveness of a page to user interactions — how quickly the page responds when a user clicks a button, taps a link, or types in a field. Heavy JavaScript that blocks the browser's main thread is the primary cause of poor INP.

  • Good: under 200 milliseconds
  • Needs improvement: 200–500ms
  • Poor: over 500ms

CLS — Cumulative Layout Shift

Measures unexpected movement of content while the page is loading. If an image loads and pushes text down, or a banner pops in and moves the button you were about to click — that's layout shift. It's frustrating and signals a poorly built page.

  • Good: under 0.1
  • Needs improvement: 0.1–0.25
  • Poor: over 0.25

Fix CLS by: Always specifying width and height on images, never inserting content above existing content dynamically, and using CSS transforms for animations instead of properties that affect layout.

Practical Performance Tips

Image Optimisation

Images are almost always the biggest performance win available. Large, unoptimised images can account for 80%+ of a page's total transfer size.

  • Convert images to WebP format — typically 25–35% smaller than JPEG at equivalent quality. Use Squoosh (free, browser-based) to convert.
  • Always set explicit width and height attributes on images to prevent CLS.
  • Use loading="lazy" on images below the fold — they only download when needed.
  • Use srcset to serve different sizes to different devices — no need to load a 2000px image on a 375px phone.
  • Compress every image before uploading. TinyPNG or Squoosh can reduce file sizes by 60–80%.
HTML — Optimised Image
<img src="hero.webp"alt="Hero description"width="1200"height="600"loading="eager"fetchpriority="high"><!-- Use loading="lazy" for images below the fold --><!-- fetchpriority="high" on hero images helps LCP -->

Minification

Remove whitespace, comments, and unnecessary characters from CSS and JavaScript files. Minified files load faster. Most deployment platforms (Netlify, Vercel, Cloudflare Pages) minify assets automatically on deploy. For WordPress, caching plugins like WP Super Cache handle this.

Caching

Tell browsers to cache static assets (images, CSS, JS) so returning visitors don't re-download them. Set long cache lifetimes (1 year) for files with versioned URLs — change the filename whenever the file changes. Set shorter lifetimes for HTML pages so updates reach users promptly.

Netlify _headers — Caching
/assets/* Cache-Control: public, max-age=31536000, immutable/*.css Cache-Control: public, max-age=31536000, immutable/*.js Cache-Control: public, max-age=31536000, immutable/*.html Cache-Control: public, max-age=0, must-revalidate

Content Delivery Network (CDN)

A CDN stores copies of your site's files on servers around the world. When a visitor loads your site, files are served from the nearest server — reducing latency dramatically. Cloudflare Pages, Netlify, and Vercel all include a global CDN at no extra cost. For WordPress sites, Cloudflare's free tier acts as a CDN and performance layer in front of your host.

Font Loading

Web fonts can cause FOIT (Flash of Invisible Text) or FOUT (Flash of Unstyled Text) if not loaded carefully. Best practices: use font-display: swap so text shows immediately in a fallback font while the custom font loads; preconnect to the font server; subset fonts to only include the characters you need.

HTML — Fast Font Loading
<!-- Preconnect to font server --><link rel="preconnect"href="https://fonts.googleapis.com"><link rel="preconnect"href="https://fonts.gstatic.com"crossorigin><!-- Load only the weights you actually use --><link href="https://fonts.googleapis.com/css2?family=Sora:wght@400;600;700&display=swap"rel="stylesheet">

Defer and Async Scripts

By default, <script> tags in HTML block page rendering until the script is downloaded and executed. Use defer to download in the background and execute after HTML parsing, or async to download in the background and execute immediately when done. Always use one of these unless a script must run synchronously.

Performance Checklist

Run through this checklist on every site before launch. Progress is saved in your browser.

Images

All images are in WebP or AVIF format
All images are compressed — no image over 300KB without strong reason
All images have explicit width and height attributes set
Below-fold images use loading="lazy"
Hero image uses fetchpriority="high" and is preloaded

Code & Assets

CSS and JavaScript files are minified
Scripts use defer or async — no render-blocking JS
No unused CSS or JS is loaded (remove unused libraries)
Fonts use display=swap and font server is preconnected

Server & Infrastructure

Site is served via a CDN (Cloudflare Pages, Netlify, Vercel, or similar)
Long-lived cache headers are set for static assets
Gzip or Brotli compression is enabled on the server
HTTP/2 or HTTP/3 is enabled (most modern hosts do this by default)

Testing

PageSpeed Insights mobile score is 90+
CLS score is below 0.1 — no unexpected layout shifts
LCP is under 2.5 seconds on mobile
GTmetrix score is B or above with no critical warnings
Note: Your checklist progress is saved in your browser. It will still be here next time you visit.