Page Speed Optimization: Why Speed Matters and How to Fix a Slow Website
Why page speed matters
Page speed isn't a nice-to-have — it directly impacts your bottom line. Research from Google and others is unambiguous:
- 53% of mobile users abandon a site that takes longer than 3 seconds to load.
- Every 100ms of latency costs Amazon roughly 1% in sales. For smaller businesses, the percentage impact is even higher.
- Google uses page speed as a ranking factor. Since the Page Experience update, Core Web Vitals (which include load speed) directly influence search rankings.
- Conversion rates drop by ~4.4% for each additional second of load time in the 0-5 second range.
Speed also affects perception of quality. A fast site feels professional and trustworthy. A slow one feels broken — even if the content is identical.
How to measure your page speed
You can't fix what you don't measure. Use these tools to establish your baseline:
- Google PageSpeed Insights — Analyzes both mobile and desktop performance using real Chrome user data (CrUX) and Lighthouse. Gives you Core Web Vitals scores and specific fix recommendations.
- WebPageTest.org — Advanced testing with filmstrip view, waterfall charts, and multi-step transactions. Test from different locations and connection speeds.
- Chrome DevTools (Lighthouse) — Built into Chrome. Open DevTools → Lighthouse tab → run an audit. Great for local development testing.
- Chrome DevTools (Network tab) — See every request, its size, timing, and waterfall. Filter by type to find the heaviest resources.
- Google Search Console — Core Web Vitals report shows real-user performance across your entire site, grouped by status.
Always test on mobile with throttled connections. Your development machine on fast Wi-Fi is not representative of real users. PageSpeed Insights simulates a mid-tier phone on a 4G connection — that's the experience most users actually have.
Tip
Run PageSpeed Insights on your 5 highest-traffic pages first. Fix the issues that appear on all of them — you'll get the biggest improvement for the least effort.
Common causes of slow websites
Most slow websites suffer from a combination of these issues:
- Unoptimized images — The single most common culprit. A single 4MB hero image can destroy load times. See our image optimization guide.
- Too much JavaScript — Heavy JS frameworks, analytics scripts, chat widgets, and third-party embeds all compete for the main thread. Each script adds parse, compile, and execution time.
- No caching — Without proper cache headers, browsers re-download every resource on every visit. See our caching guide.
- Render-blocking resources — CSS and synchronous JS in the
<head>block the browser from rendering anything until they're fully loaded. - Slow server response (TTFB) — If the server takes 2+ seconds to respond, no frontend optimization can save you. Causes include slow database queries, no server-side caching, and distant hosting.
- Too many HTTP requests — Each request has latency overhead. Pages with 100+ requests have compounding delays.
- No CDN — Serving assets from a single origin server means users far from that server experience high latency.
- Web fonts — Multiple font families and weights (especially from Google Fonts) add multiple render-blocking requests.
Server-side speed fixes
Start from the server and work outward:
Reduce Time to First Byte (TTFB):
- Use a CDN (Cloudflare, Fastly, AWS CloudFront) to serve content from edge nodes near the user
- Enable server-side caching — cache database queries and rendered HTML
- Optimize database queries — add indexes, reduce N+1 queries, paginate large result sets
- Upgrade hosting if needed — shared hosting is often the bottleneck for growing sites
Enable compression:
# Nginx gzip configuration
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 256;
gzip_vary on;
# For even better compression, enable Brotli:
brotli on;
brotli_types text/plain text/css application/json application/javascript text/xml;
brotli_comp_level 6;
Brotli compression typically achieves 15-20% better compression ratios than gzip for text resources. Most modern CDNs support Brotli out of the box.
Tip
If your TTFB exceeds 600ms, focus on server-side fixes before optimizing the frontend. No amount of image compression can compensate for a 3-second server response.
Frontend speed fixes
Eliminate render-blocking resources:
<!-- Defer non-critical JS -->
<script src="/analytics.js" defer></script>
<!-- Async load non-critical CSS -->
<link rel="preload" href="/non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<!-- Preconnect to third-party origins -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
Reduce JavaScript payload:
- Audit third-party scripts — remove unused analytics, tracking pixels, and chat widgets. Each one you remove is an instant win.
- Code-split your bundle — load only the JS needed for the current page. In Next.js, dynamic imports handle this automatically.
- Tree-shake unused code — modern bundlers (Webpack 5, Vite, Turbopack) do this, but only if you use ES module imports.
- Replace heavy libraries — swap Moment.js (68KB gzipped) for date-fns (tree-shakeable) or the native Intl API.
Optimize web fonts:
- Use
font-display: swapto show text immediately with a fallback font - Subset fonts to include only the characters you need
- Self-host fonts instead of loading from Google Fonts (saves a DNS lookup and connection)
- Limit to 2 font families and 3-4 weights maximum
Setting a performance budget
A performance budget is a set of limits you define for your site and enforce during development. Without one, performance degrades over time as features and content are added.
Recommended budgets for most websites:
- Total page weight: under 1.5 MB (ideally under 1 MB)
- JavaScript: under 300 KB compressed
- LCP: under 2.5 seconds
- TTFB: under 600ms
- Number of requests: under 50
Enforce budgets in your CI/CD pipeline using Lighthouse CI or bundlesize. When a pull request pushes you over budget, you have a conversation about what to cut — not a surprise performance regression in production.
// lighthouse-ci config example (lighthouserc.js)
module.exports = {
ci: {
assert: {
assertions: {
'first-contentful-paint': ['warn', { maxNumericValue: 2000 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'total-byte-weight': ['warn', { maxNumericValue: 1500000 }],
},
},
},
};Frequently Asked Questions
Related Articles
Check how your website performs in this area
Get Your Growth Score