How to Speed Up Your Website: 20+ Proven Techniques for 2026

Website speed is not just a developer concern — it directly affects revenue, search rankings, and user experience. Google's research shows a 1-second delay in mobile load time reduces conversions by up to 20%. A page that goes from 3 seconds to 1 second sees a 2× improvement in bounce rate. Every millisecond counts. This guide covers every proven technique — from quick wins you can implement today to architectural changes that deliver lasting performance gains.

Whether you run a WordPress blog, a Shopify store, or a custom-built app, the techniques below apply. We've ordered them by impact, starting with the changes that move the needle most for the least effort.

Quick answer: The single biggest website speed win in 2026: convert all JPEG and PNG images to WebP (saves 25–35% per image) and lazy-load images below the fold. Images are the LCP element on ~70% of pages. Use Convertlo to convert to WebP for free — no upload required.

Why Speed Matters: Quick Numbers

53%
of mobile users leave if a page takes over 3 seconds to load (Google)
20%
drop in conversions per 1-second delay in mobile load time (Deloitte)
+SEO
Good Core Web Vitals scores give a direct Google ranking advantage
1%
revenue lost per 100ms of latency — Amazon's internal calculation

Step 1 — Measure First

Before optimising anything, measure. You need a baseline so you can see exactly what's slow and verify that your changes are working.

  • Google PageSpeed Insights — free, shows Core Web Vitals (LCP, INP, CLS) from real Chrome users in the field, plus lab-based diagnostics
  • GTmetrix — waterfall chart, detailed breakdown by resource type, historical tracking
  • WebPageTest — real-device testing, filmstrip view, advanced metrics including TTFB, video comparison
  • Chrome Lighthouse — DevTools → Lighthouse tab, runs locally, great for iterating during development
  • Chrome DevTools Network tab — filter by image/JS/CSS, sort by size or duration, see exactly what's largest and slowest

Run tests on mobile — Google indexes and ranks mobile versions first. A site that feels fast on desktop Wi-Fi can fail completely on mobile 4G, which is where Google measures your ranking signals.

Step 2 — Optimize Images (Biggest Win)

Images account for 50–75% of total page weight on most sites. This is consistently where the biggest performance gains are found — and where you should spend most of your optimisation effort.

Switch to WebP

JPEG files are 25–35% larger than equivalent WebP files at the same visual quality. Converting your images to WebP is the single highest-ROI change you can make — no design changes, no code rewrites, just smaller files that load faster. Google's PageSpeed Insights explicitly flags "Serve images in next-gen formats" as an audit, and switching to WebP resolves it.

Convert Your Images to WebP — Free & Instant

Upload your JPGs and get WebP files back in seconds. No account, no upload to a server — runs entirely in your browser.

Use the HTML <picture> element to serve WebP to modern browsers with a JPEG fallback for older ones:

<picture>
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="Hero image" width="1200" height="630">
</picture>

Add Lazy Loading

Images below the fold should not load until the user scrolls near them. One attribute does this — and it is supported natively in all modern browsers with no JavaScript required:

<img src="product.webp" alt="Product" loading="lazy" width="400" height="400">

Add loading="eager" (or omit the attribute) on above-the-fold images. Lazy loading the LCP image is one of the most common mistakes developers make — it directly harms your LCP score because the browser deprioritises loading that image.

Set Width and Height on All Images

Images without explicit dimensions cause Cumulative Layout Shift (CLS) — the page jumps visibly as images load in, which is jarring for users and penalised by Google. Always specify both attributes:

<img src="photo.webp" alt="Photo" width="800" height="600">

Even if you resize the image via CSS, the browser uses the width/height ratio to reserve space before the image loads, preventing layout shifts entirely.

Compress Images

Even WebP can be larger than necessary if exported at quality 100. Use quality 80–85 for photographs and UI photos — the difference is invisible to users but the file size difference is significant. Use lossless compression for icons, logos, and UI graphics with sharp edges. Convertlo's free image compressor lets you fine-tune compression without visible quality loss.

Serve Responsive Images

Don't serve a 2400px wide image to a 375px phone screen — that's serving 6–10× more data than needed. Use the srcset attribute to let the browser pick the right size:

<img
  src="photo-800.webp"
  srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w"
  sizes="(max-width: 600px) 100vw, 800px"
  alt="Product" loading="lazy">

Step 3 — Enable Browser Caching

Static assets (images, CSS, JS, fonts) don't change often. Tell browsers to cache them locally so returning visitors don't re-download the same files on every page load. For immutable, content-hashed assets:

Cache-Control: public, max-age=31536000, immutable

For HTML pages that change more often:

Cache-Control: public, max-age=3600, stale-while-revalidate=86400

In Nginx, apply long cache headers to all static assets in one rule:

location ~* \.(woff2|jpg|webp|png|svg|css|js)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

Step 4 — Enable Gzip or Brotli Compression

Text assets (HTML, CSS, JS, JSON, SVG) compress dramatically — typically 60–80% smaller over the wire. Brotli is newer and compresses 20–30% better than Gzip for text assets. Most modern browsers support Brotli; Gzip is the universal fallback.

In Nginx with the ngx_brotli module:

brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json image/svg+xml;

In Apache via .htaccess:

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css application/javascript
</IfModule>

Verify that compression is active: curl -H "Accept-Encoding: br" -I https://yoursite.com — look for Content-Encoding: br in the response headers. If you see Content-Encoding: gzip, Brotli isn't enabled but Gzip is working.

Step 5 — Minify CSS, JavaScript, and HTML

Whitespace, comments, and verbose variable names add kilobytes to every file. Minification removes them without changing functionality. On a large codebase this can reduce JS bundle size by 20–40% before compression.

  • CSS/JS: Use Vite, webpack, or esbuild — they minify automatically on production build with zero configuration
  • HTML: html-minifier-terser for static sites; Cloudflare's Speed → Optimization panel has automatic HTML minification for sites behind their CDN
  • Quick check: compare gzipped vs raw size with PageSpeed Insights' "Reduce unused CSS/JS" audit — if the potential saving is large, minification is missing

Step 6 — Remove Unused CSS and JavaScript

Most websites load entire CSS frameworks (Bootstrap, Tailwind CDN) and JavaScript libraries but use 5–10% of the code. The rest is downloaded, parsed, and compiled by the browser for nothing.

  • Use Chrome Coverage tool (DevTools → More tools → Coverage) — run it while navigating your page and it shows exactly how many bytes of each file are unused
  • Remove unused CSS with PurgeCSS — scans your HTML templates and removes any CSS selectors that are never used. Works automatically with Tailwind via its built-in purge configuration
  • Use dynamic import() to code-split JavaScript — load modules only when they are actually needed:
// Instead of a top-level import that loads on every page:
// import Chart from './chart.js';

// Load only when the user opens the chart section:
const chart = await import('./chart.js');

Step 7 — Defer Non-Critical JavaScript

JavaScript blocks HTML parsing by default — the browser stops building the DOM until each script tag finishes downloading and executing. This directly delays the LCP. Use defer for scripts that don't need to run before the page renders:

<!-- Blocks parsing — avoid for non-critical scripts -->
<script src="analytics.js"></script>

<!-- Runs after HTML is fully parsed, in order — use this -->
<script src="analytics.js" defer></script>

<!-- Downloads in parallel, runs immediately when ready — for independent scripts -->
<script src="widget.js" async></script>

Load analytics (GTM, GA4, Meta Pixel) only on first user interaction — not on page load. This eliminates the analytics network request from your critical path entirely:

function loadAnalytics() {
  if (window._analyticsLoaded) return;
  window._analyticsLoaded = true;
  // inject GTM script here
}
['click', 'scroll', 'keydown'].forEach(e =>
  document.addEventListener(e, loadAnalytics, { once: true, passive: true }));
setTimeout(loadAnalytics, 4000);

Step 8 — Optimize Fonts

Web fonts are a common source of render-blocking and FOIT (Flash of Invisible Text), where the browser shows blank text while waiting for the font to download. The correct pattern eliminates both problems:

<!-- Preload the font file — starts downloading immediately -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>

<!-- Load font CSS asynchronously — never blocks rendering -->
<link rel="preload" href="/fonts.css" as="style"
  onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/fonts.css"></noscript>

In your font-face CSS, use font-display: swap to show a fallback system font immediately while the web font loads, eliminating invisible text:

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter.woff2') format('woff2');
  font-display: swap;
}

Serve fonts from your own domain rather than Google Fonts CDN. Self-hosting eliminates a cross-origin DNS lookup and TCP handshake on the critical path, which can save 100–200ms on first visit — particularly important for LCP.

Step 9 — Use a Content Delivery Network (CDN)

A CDN caches your static assets on servers worldwide. When a user requests your page, they download assets from the nearest edge node instead of your origin server. The result: TTFB drops from 200–400ms to 20–50ms for international users.

  • Cloudflare — free tier, automatic WebP conversion (Polish feature), Brotli, HTTP/3, one of the largest CDN networks globally. 5-minute setup via DNS change.
  • Fastly — enterprise-grade, instant cache purge, excellent for APIs and dynamic content
  • AWS CloudFront — integrates with S3 and EC2, pay-per-use pricing, suitable for complex AWS architectures

For WordPress or any site: activate Cloudflare's free plan. Change your DNS nameservers, enable proxy mode, and you immediately get global CDN, automatic HTTPS, Brotli compression, and DDoS protection — with zero server configuration.

Step 10 — Reduce Server Response Time (TTFB)

Time to First Byte (TTFB) is how long the browser waits before receiving the first byte of HTML from your server. Target: under 200ms. If your TTFB is high, every other metric suffers. Common fixes:

  • Upgrade to HTTP/2 or HTTP/3 — multiplexed requests, no head-of-line blocking, dramatically better for pages with many resources
  • Enable server-side caching — Redis or Memcached for database query results; full-page caching for CMS pages that don't change per user
  • Use a faster hosting tier — shared hosting often has TTFB of 800ms+. Moving to a VPS (DigitalOcean Droplet, Hetzner Cloud) typically brings TTFB to under 100ms
  • Enable PHP opcache (built into PHP 8+) — dramatically reduces PHP execution time on WordPress and Laravel applications
  • Add database indexes on columns frequently used in WHERE, JOIN, and ORDER BY clauses — a missing index can turn a 5ms query into a 2-second query

Step 11 — Preconnect to Critical Third-Party Origins

If your page fetches resources from third-party domains, the browser must do a DNS lookup, TCP handshake, and TLS negotiation before it can make the first request. Resource hints can start this process early:

<!-- Preconnect: full TCP+TLS warmup — use only for resources needed in first 3s -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- dns-prefetch: DNS only — use for resources needed soon but not immediately -->
<link rel="dns-prefetch" href="//cdn.example.com">

Only preconnect to origins that serve resources in the critical render path. Too many preconnects waste bandwidth — each one initiates a TCP+TLS handshake even if the connection is never used.

Step 12 — Preload Your LCP Resource

The LCP element (usually the hero image or main heading) should start loading as early as possible — ideally before the browser has parsed the rest of the HTML. Add a preload hint in <head>:

<link rel="preload" href="/images/hero.webp" as="image" type="image/webp">

If your LCP is a CSS background image, preloading is especially critical. Browsers don't discover CSS background images until the stylesheet is downloaded and parsed — which can be 200–500ms after navigation starts. A preload hint bypasses this delay entirely.

Step 13 — Eliminate Render-Blocking Resources

CSS in <head> is render-blocking by default — the browser will not paint anything until all stylesheets are downloaded and parsed. For non-critical CSS (styles used only below the fold), load it asynchronously:

<link rel="preload" href="non-critical.css" as="style"
  onload="this.onload=null;this.rel='stylesheet'">

Inline critical CSS (all styles needed for above-the-fold content) directly in a <style> tag in <head>. This eliminates a full network round trip for the initial render — the browser can paint the visible page immediately without waiting for an external CSS file.

Step 14 — Reduce Redirects

Each HTTP redirect adds a full round trip — typically 100–300ms of pure latency with nothing to show for it. Common offenders:

  • http://https:// — fix by configuring your server to serve HTTPS by default, or set HSTS (HTTP Strict Transport Security) so browsers never attempt the http:// version
  • www.site.comsite.com (or vice versa) — fix at the DNS level so the canonical domain resolves directly without a redirect
  • Redirect chains (A→B→C) — common after site migrations. Collapse to a single redirect (A→C)

Check for redirect chains: curl -I http://yoursite.com and count the Location: headers in the response. Each one is a round trip you can eliminate.

Step 15 — Eliminate Layout Shift (CLS)

Cumulative Layout Shift (CLS) penalises pages where content jumps around as it loads — which is both annoying to users and a Google ranking factor. A CLS score above 0.1 is "Needs improvement"; above 0.25 is "Poor".

  • Images without dimensions → add width and height attributes to every <img> tag
  • Ads loading in → reserve space with min-height on the ad container so content doesn't shift when the ad loads
  • Fonts swapping → use font-display: swap combined with preloaded font files; the text reflow from swap is less disruptive than invisible text
  • Dynamic content injecting above existing content → inject new elements below the fold, or use CSS aspect-ratio to reserve correct proportional space for content that hasn't loaded yet

Step 16 — Use HTTP/2 or HTTP/3

HTTP/1.1 limits browsers to 6 concurrent connections per domain. With 30–80 resources on a typical page, this creates a queue where resources wait for earlier ones to finish. HTTP/2 solves this by multiplexing unlimited requests over a single TCP connection. HTTP/3 goes further — it uses the QUIC protocol over UDP, which handles packet loss better than TCP, delivering meaningful improvements on lossy mobile networks.

Most modern CDNs and hosting providers support HTTP/2 automatically. HTTP/3 is available on Cloudflare, Fastly, and Vercel. Verify: curl -I --http2 https://yoursite.com — look for HTTP/2 in the response.

Step 17 — Implement a Service Worker

Service workers cache assets locally in the browser after the first visit. Subsequent visits can load those assets from the local cache at memory speeds — making repeat visits near-instant regardless of network conditions:

// sw.js — cache-first strategy for images
self.addEventListener('fetch', event => {
  if (event.request.destination === 'image') {
    event.respondWith(
      caches.match(event.request).then(r => r || fetch(event.request))
    );
  }
});

Service workers are most effective for static assets: images, fonts, CSS, and JavaScript that rarely change. They're less suitable for frequently-changing data or API responses that must always be fresh.

Step 18 — Reduce Third-Party Scripts

Third-party scripts — chat widgets, social media embeds, tag managers with dozens of tags, survey tools, A/B testing platforms — are a leading cause of slow pages that are hard to diagnose because they are outside your control.

  • Audit with WebPageTest's "Block" feature — block scripts one at a time and measure the performance impact of each
  • Load chat widgets only on interaction — when the user clicks the chat button, not on page load
  • Replace heavy social media embeds (Twitter/X, Instagram) with static screenshots that load the real embed only when clicked — saves 200–500ms per embed
  • Use Google Tag Manager's firing rules to load tags only on pages where they are relevant — analytics on all pages, checkout scripts only on checkout pages

Step 19 — Database and Backend Optimisation

For dynamic sites (WordPress, custom apps, e-commerce), the database is often the hidden bottleneck — the server responds slowly because it is waiting for slow queries, not because of anything in the front end.

  • Add database indexes on columns used in WHERE and JOIN clauses — especially on foreign keys, status columns, and date ranges. EXPLAIN in MySQL/PostgreSQL shows you which queries are doing full table scans
  • Cache query results with Redis or Memcached — store the result of expensive queries for 60–300 seconds; most pages don't need real-time data
  • Enable PHP opcache (built into PHP 8+, configure in php.ini) — compiles PHP to bytecode on first execution and caches it, eliminating recompilation on every request
  • Paginate large result sets — never fetch 10,000 rows for a list page. Use LIMIT and OFFSET, or cursor-based pagination for better performance
  • Use a query cache layer — for WordPress: WP Rocket or W3 Total Cache handle this with minimal configuration

Step 20 — Platform-Specific Quick Wins

WordPress

  • Install WP Rocket or LiteSpeed Cache — one plugin handles minification, lazy loading, full-page caching, CDN integration, and defer of non-critical scripts
  • Use Imagify or ShortPixel to automatically convert uploaded images to WebP — new uploads are converted transparently, no manual work required
  • Disable unused plugins — each active plugin adds PHP execution overhead even if it does nothing on most pages
  • Use a lightweight theme (GeneratePress, Kadence, Blocksy) — avoid heavy page builders (Elementor, Divi) for performance-critical landing pages

Shopify

  • Compress and convert product images to WebP before uploading — Shopify serves images through its own CDN but doesn't automatically convert legacy formats
  • Shopify's built-in image CDN (powered by Cloudflare) serves images from edge nodes automatically — take advantage of this by using their img_url filter for all product images
  • Avoid installing too many apps — each Shopify app typically injects additional JavaScript that runs on every storefront page
  • Add loading="lazy" to product grid images in your theme's Liquid templates

Static Sites (HTML/JS)

  • Use Vite or Next.js — both include automatic code splitting, tree shaking, and image optimisation out of the box
  • Deploy to Vercel or Netlify — both serve from a global CDN with HTTP/3 by default and have generous free tiers
  • Pre-render pages at build time (Static Site Generation) rather than fetching data client-side — the HTML is ready immediately with no server-side rendering latency

Quick Wins Checklist

Do today — under 30 minutes each

  • Convert images to WebP — biggest single performance win
  • Add loading="lazy" to all images below the fold
  • Add width and height attributes to all img elements
  • Enable Cloudflare free plan on your domain — instant CDN, Brotli, HTTP/3
  • Run PageSpeed Insights and fix the top 3 flagged Opportunities

This week

  • Enable Brotli/Gzip compression on your server
  • Add Cache-Control headers to all static assets (images, CSS, JS, fonts)
  • Load analytics scripts lazily (on first user interaction, not page load)
  • Audit and remove unused CSS with Chrome DevTools Coverage tool
  • Preload your LCP image with <link rel="preload" as="image">

This month

  • Move fonts to your own domain and preload the .woff2 files
  • Implement critical CSS inline in <head> to eliminate render-blocking stylesheet requests
  • Audit and remove or defer slow third-party scripts
  • Set up a CDN for static assets if not already using one

Frequently Asked Questions

What is the fastest way to speed up a website?
The highest-ROI single change is converting images to WebP and adding lazy loading. Images are the largest assets on most pages — switching from JPEG to WebP reduces image weight by 25–35%, and lazy loading stops off-screen images from blocking the initial load. Together these two changes can cut page weight by 40–60% with no visible quality difference.
How do I check my website speed?
Use Google PageSpeed Insights (free, measures Core Web Vitals from real Chrome users), GTmetrix (detailed waterfall chart), WebPageTest (advanced, real device testing), or Chrome DevTools Lighthouse tab (runs locally). Run tests from multiple locations and on both mobile and desktop — Google ranks based on mobile performance.
What is a good website load time in 2026?
Google's Core Web Vitals targets: Largest Contentful Paint (LCP) under 2.5 seconds, Interaction to Next Paint (INP) under 200ms, Cumulative Layout Shift (CLS) under 0.1. For overall page load, aim for under 3 seconds on a 4G mobile connection — studies show 53% of mobile users abandon pages that take longer than 3 seconds to load.
Does website speed affect SEO?
Yes, directly. Google uses Core Web Vitals (LCP, INP, CLS) as ranking signals. A page that scores "Good" on all three has a measurable ranking advantage over a slower competitor with identical content. Faster pages also have lower bounce rates and higher conversion rates, which Google interprets as positive engagement signals.
How much does a CDN speed up a website?
A CDN typically reduces Time to First Byte (TTFB) by 40–60% for users far from your origin server. For a US-hosted site serving users in Europe or Asia, a CDN can cut latency from 200–400ms to 20–50ms by serving cached assets from edge nodes near the user. Cloudflare, Fastly, and AWS CloudFront all offer free or low-cost tiers.
Convertlo Editorial Team
The Convertlo team writes practical guides on image formats, file conversion, and web performance. All technical content is verified against current format specifications and tested in real browsers.
convertlo.pro