A slow website loses visitors before they read a word. Google's research found that the probability of a visitor bouncing increases 32% as load time goes from 1 to 3 seconds — and that's before accounting for the direct ranking impact. Here's how to fix it.
Why speed matters for SEO
Since 2021, page speed has been an official ranking factor via Google's Core Web Vitals. The three metrics are:
- LCP (Largest Contentful Paint): how fast the main content loads. Target: under 2.5 seconds.
- CLS (Cumulative Layout Shift): how much the layout shifts as elements load. Target: under 0.1.
- INP (Interaction to Next Paint): how quickly the page responds to user input. Target: under 200ms.
Pages that score "Good" on all three have a ranking advantage over comparable pages that score "Needs Improvement" or "Poor". For competitive queries, this can be the deciding factor.
Beyond rankings, speed affects conversions directly. A one-second delay in load time reduces conversions by an average of 7%, according to Akamai research. A site that loads in 1 second will, everything else equal, convert visitors better than one that loads in 4 seconds — regardless of how good the content is.
See the detailed Core Web Vitals guide for the specific measurement methods and fixes for each metric.
How to measure your speed
Before fixing anything, measure what's actually slow. Several free tools do this:
Google PageSpeed Insights
The authoritative source. Go to pagespeed.web.dev, enter your URL, and run the test. It shows two types of data:
- Field data (real user data): measurements from actual visitors, pulled from the Chrome User Experience Report. This is what Google uses for ranking. Only available if your page has enough traffic.
- Lab data (simulated): a controlled test with specific device and network settings. Always available and useful for diagnosing issues, even on new sites.
The Opportunities and Diagnostics sections tell you exactly what's slowing the page down and how much each fix would help.
Google Search Console
The Core Web Vitals report (under Experience in the left sidebar) shows field data for your whole site, grouped by "Good", "Needs Improvement", and "Poor". It flags specific URLs that are failing so you can prioritise which pages to fix first. See the GSC setup guide if you haven't connected your site yet.
GTmetrix
Offers a waterfall view — a visual timeline of every resource the page loads, in order, with how long each takes. Useful for spotting specific slow resources that PageSpeed Insights doesn't highlight as clearly.
Fix #1: Images (highest impact)
Unoptimised images are the single most common cause of slow websites. A single full-resolution photo uploaded directly from a camera can be 5–10MB — on a typical page that should load in under a second. Here's the full fix:
Use the right format
- Photos: use WebP instead of JPEG. WebP is 25–35% smaller at the same quality. Most modern browsers support it. If you need a fallback, use a
<picture>element. - Graphics with transparency: WebP instead of PNG. Dramatically smaller files.
- Icons and logos: SVG — infinitely scalable, tiny file sizes.
- Hero images and backgrounds: consider AVIF, which is even smaller than WebP but has slightly less browser support. Use with a WebP fallback.
Compress before uploading
Even WebP images should be compressed. Free tools: Squoosh (by Google, in-browser, excellent quality control) or TinyPNG (simpler, handles batch uploads). Aim for images under 100KB for standard content images, under 200KB for hero images.
Resize to display size
Don't upload a 4000×3000px image and display it at 400×300px. The browser has to download the full image and then scale it down — wasting data. Resize to the actual display dimensions before uploading.
Set explicit dimensions
Add width and height attributes to every <img> tag. Without them, the browser doesn't know how much space to reserve until the image loads — causing layout shift (a CLS problem) as other elements jump around.
<img src="hero.webp" alt="Web design studio" width="1200" height="630">
Lazy load below-the-fold images
Add loading="lazy" to any image that's not visible on initial page load. This tells the browser to wait until the image is about to scroll into view before downloading it — reducing the initial page weight significantly.
<img src="portfolio-work.webp" alt="Portfolio example" width="800" height="600" loading="lazy">
Don't add loading="lazy" to your hero image or any image visible above the fold on load — it'll delay the LCP score.
Fix #2: Hosting and server response time
Time to First Byte (TTFB) is how long the browser waits before receiving the first byte of the page. A TTFB over 800ms is a problem. If your TTFB is slow, no amount of image optimisation will fully compensate.
Common causes of slow TTFB:
- Cheap shared hosting: on a shared server, hundreds of other websites compete for the same CPU and memory. Under load, TTFB can climb to 2–3 seconds. Upgrading to a VPS or a platform like Vercel, Cloudflare Pages, or Netlify typically drops TTFB to under 200ms for static sites.
- No server-side caching: on WordPress, every page request normally rebuilds the page from the database. A caching plugin (WP Rocket, W3 Total Cache) serves pre-built HTML instead — dramatically reducing TTFB.
- No CDN: a Content Delivery Network stores copies of your site on servers worldwide. Visitors get served from the closest server rather than your origin. Cloudflare's free plan is usually sufficient for most small sites.
Fix #3: JavaScript and CSS
JavaScript and CSS files can block page rendering — the browser won't display the page until it's finished downloading and processing them. This is called "render-blocking".
Remove unused CSS: many themes and page builders load enormous stylesheets, most of which aren't used on any given page. Tools like PurgeCSS can remove unused rules. PageSpeed Insights flags the estimated savings.
Defer non-critical JavaScript: scripts that don't need to run before the page displays (analytics, chat widgets, marketing tools) should load after the main content. Add defer or async to script tags, or move them to the bottom of the <body>.
<script src="analytics.js" defer></script>
Minify CSS and JS: remove whitespace, comments, and unnecessary characters from code files. Most build tools (Vite, webpack, Parcel) do this automatically. For WordPress, plugins like Autoptimize handle it.
Fix #4: Web fonts
Web fonts add HTTP requests and can cause text to be invisible while loading (FOIT — Flash of Invisible Text) or jump when the font swaps in (contributing to CLS).
Preconnect to font providers: add <link rel="preconnect"> tags for any external font source to start the DNS lookup early:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Use font-display: swap: tells the browser to show a fallback font immediately and swap to the web font when it's ready. Prevents invisible text and keeps the page readable during load.
Limit font variants: every weight and style (regular, bold, italic) is a separate file download. Load only what you actually use. Many sites load 6–8 font variants and use 2.
Self-host fonts: downloading fonts from Google Fonts requires a DNS lookup and connection to Google's servers. Self-hosting avoids this and gives you direct control over caching. Google Fonts Helper makes it easy to download and self-host any Google Font.
Fix #5: Caching
Caching means storing a copy of a file so it doesn't have to be downloaded again on repeat visits. Properly configured caching means returning visitors load your site almost instantly.
Browser caching: set cache headers on static assets (images, CSS, JS) so browsers store them locally. For assets that rarely change, a cache lifetime of a year is reasonable. This is configured on the server or CDN.
CDN caching: platforms like Cloudflare, Vercel, and Netlify serve cached copies from edge locations close to each visitor. Static sites and Jamstack sites get this automatically. WordPress with a caching plugin can approximate this.
WordPress caching plugins: WP Rocket (paid) is the most comprehensive. WP Super Cache and W3 Total Cache are solid free alternatives. They generate static HTML from your dynamic WordPress pages so the server doesn't rebuild every page on every request.
Fix #6: Third-party scripts
Every third-party script — chat widgets, cookie banners, heatmap tools, social share buttons, marketing pixels, YouTube embeds — adds HTTP requests, JavaScript execution, and potentially render-blocking behaviour. They're also out of your control: if the third party's server is slow, your page is slow.
Audit what you're running by looking at the Network tab in Chrome DevTools. You'll often find scripts from services you no longer actively use.
For scripts you do need:
- Load them with
deferorasync - Use a tag manager (Google Tag Manager) to centralise and control when they fire
- Lazy-load embeds like YouTube videos — use a facade (a placeholder image that loads the full embed only when clicked)
Mobile vs desktop
Google uses mobile-first indexing, meaning it primarily uses the mobile version of your site for ranking. Your mobile speed score is the one that matters most for SEO — but many sites that perform well on desktop score poorly on mobile due to the simulated slower CPU and network conditions.
PageSpeed Insights shows separate mobile and desktop scores. Focus on the mobile score. If there's a big gap, the usual causes are images not being responsive (serving desktop-sized images to mobile), too much JavaScript, or no lazy loading.
Responsive images using the srcset attribute serve different image sizes to different screen widths — smaller images to smaller screens, which is both faster and more bandwidth-efficient:
<img
src="hero-800.webp"
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
alt="Web design studio"
width="1200" height="630"
>
Every Bisyri project is built for speed — optimised images, minimal JavaScript, fast hosting, and Core Web Vitals targets met before launch. Get in touch to find out what a rebuild or performance audit would involve for your site.
The short version
Start with images — convert to WebP, compress, resize to display dimensions, set explicit dimensions, lazy-load below the fold. Then check your TTFB and upgrade hosting or add Cloudflare if it's over 800ms. Defer non-critical scripts. Limit web font variants. Set up caching. Measure before and after with PageSpeed Insights. For the specific Core Web Vitals fixes, see the Core Web Vitals guide.