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%.
<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.
/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-revalidateContent 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.
<!-- 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.