A one-second delay in page load time can reduce conversions by 7%, increase bounce rate by 11%, and drop your Google rankings. Page speed is no longer just a nice-to-have — it's a direct ranking factor via Core Web Vitals, and it's the difference between users who stay and users who leave before your page finishes loading.
The good news: most page speed problems come from a small number of fixable causes. This guide walks through how to audit your site, interpret the results, and fix the most impactful issues — all using free tools.
Step 1: Run a Page Speed Audit
Start with a baseline measurement before making any changes. Two essential free tools:
- Google PageSpeed Insights (pagespeed.web.dev) — analyses both mobile and desktop performance, powered by Lighthouse. Shows your Core Web Vitals scores and specific opportunities.
- WebPageTest (webpagetest.org) — more detailed waterfall analysis, shows exactly what loads in what order and where time is being spent.
Run both on your most important pages — homepage, main landing page, and a typical content page. Mobile scores matter more than desktop for Google rankings.
Understanding Core Web Vitals
Google's Core Web Vitals are the three metrics that feed directly into search rankings:
| Metric | What It Measures | Good | Needs Work | Poor |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | How long until the main content loads | ≤ 2.5s | 2.5–4s | > 4s |
| INP (Interaction to Next Paint) | How responsive the page is to input | ≤ 200ms | 200–500ms | > 500ms |
| CLS (Cumulative Layout Shift) | How much the page layout shifts unexpectedly | ≤ 0.1 | 0.1–0.25 | > 0.25 |
The Most Common Page Speed Problems (And How to Fix Them)
1. Render-Blocking JavaScript and CSS
Scripts and stylesheets in the <head> block the browser from rendering the page until they finish downloading and parsing. This is one of the most common causes of poor LCP scores.
Fix: Add defer or async to non-critical scripts. Move non-critical CSS to load after the page renders.
<!-- Blocks rendering ❌ -->
<script src="analytics.js"></script>
<!-- Deferred — loads after HTML parses ✅ -->
<script src="analytics.js" defer></script>
<!-- Async — loads independently, executes when ready ✅ -->
<script src="widget.js" async></script>
2. Unminified CSS and JavaScript
Unminified files contain whitespace, comments, and long variable names that add zero value to the browser but add kilobytes to every request. A typical unminified CSS file can be reduced by 20–40% through minification alone.
Fix: Minify your CSS and JS before deploying. The CSS Minifier and JS Minifier handle this instantly in the browser — paste your code, copy the minified output, done. No build pipeline required. See the full guide: How to Minify CSS and JS Without a Build Tool.
3. Large, Unoptimised Images
Images are typically the single largest contributor to page weight. A JPEG hero image exported directly from Photoshop might be 800KB when it could be 80KB at the same visual quality.
Fix:
- Convert to WebP format — typically 25–35% smaller than JPEG at the same quality
- Use responsive images with
srcsetso mobile devices don't download desktop-sized images - Add
loading="lazy"to images below the fold - Set explicit
widthandheightattributes to prevent layout shift (improves CLS)
<!-- Lazy load + explicit dimensions to prevent CLS -->
<img
src="hero.webp"
width="1200"
height="600"
loading="lazy"
alt="Description of image"
>
4. Bloated SVG Files
SVGs exported from design tools like Figma or Illustrator contain significant metadata that browsers ignore — editor comments, layer names, unused namespace declarations, excessive decimal precision. A 40KB SVG icon can often be reduced to 8KB with no visible change.
Fix: Run all SVGs through the SVG Optimizer before deploying. Typical savings are 40–70% for simple icons. Full details in SVG Optimization: Why Your SVGs Are Too Big and How to Fix Them.
5. No Browser Caching
Without caching headers, browsers re-download static assets (CSS, JS, images) on every page visit. Returning visitors pay the same performance cost as first-time visitors.
Fix: Set long cache lifetimes for versioned static assets. In Apache, add to your .htaccess:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
See the full .htaccess guide for more caching and performance directives.
6. No GZIP or Brotli Compression
Text-based assets (HTML, CSS, JavaScript, JSON) compress extremely well — typically 60–80% reduction. Without server-side compression, you're sending far more data than necessary on every request.
Fix: Enable compression in Apache via .htaccess:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
7. Too Many HTTP Requests
Every resource a page loads — CSS file, JS file, image, font — is a separate HTTP request. On HTTP/1.1, these queue up. Even on HTTP/2, excessive requests add overhead.
Fix:
- Combine multiple CSS files into one
- Use SVG sprites instead of individual icon files
- Inline critical CSS directly in the
<head> - Use system fonts or limit custom font variants
Quick Wins Checklist
| Fix | Difficulty | Impact |
|---|---|---|
| Minify CSS and JS | Low | Medium |
| Optimise and convert images to WebP | Low | High |
| Add lazy loading to below-fold images | Low | Medium |
| Optimise SVG files | Low | Low–Medium |
| Add browser caching headers | Low | High (returning visitors) |
| Enable GZIP/Brotli compression | Low | High |
| Defer non-critical JavaScript | Medium | High |
| Set explicit image dimensions | Low | High (CLS) |
Measuring After Each Change
Make one change at a time and re-run PageSpeed Insights after each one. This tells you the actual impact of each fix rather than guessing. Changes to caching and compression can take a few minutes to propagate — wait before measuring.
For ongoing monitoring, Google Search Console's Core Web Vitals report shows field data (real user measurements) rather than lab data — this is what Google actually uses for rankings. Check it monthly to catch regressions before they affect your search visibility.