Website Speed: 15 Causes of Slow Loading and Their Fixes
Images, fonts, scripts, hosting, blur effects — the things that most often slow sites down, and how many milliseconds each fix actually gives back.
A slow website almost never has one cause. It has fifteen small ones, each costing 100–400 ms, and together they turn a two-second load into a seven-second one. Below is the list of culprits ordered by damage: how many milliseconds each costs, how to find it, and how long the fix takes. It starts with measurement, because optimising blind is the fastest way to burn a week and move nothing.
2.5s
the "good" threshold for mobile LCP
200ms
the "good" threshold for INP responsiveness
0.1
maximum acceptable CLS
60%
of an average page’s weight is images
Measure first, touch second
The main mistake is staring at a single PageSpeed Insights score and trying to raise it. That score is a synthetic composite, it swings ±10 points between runs, and it says nothing about what real people experience. What you want is the individual metrics and the field data.
- 1Test three different page types — the home page, a service or product page, and your heaviest gallery page. Optimising only the home page is pointless: search traffic lands deep in the site.
- 2Separate lab data from field data. The top block of the report is real users over the last 28 days; the bottom is a simulation on an emulated slow device. Field data always wins, because those are your customers rather than a test rig.
- 3Open the Network tab with throttling set to Fast 3G and watch what loads in the first three seconds. There is usually something in there you did not expect to see at all.
- 4Record the baseline numbers before you change anything. Without a starting point you cannot prove to yourself or to a client that the fix worked.
Images: causes 1–4, the biggest lever
If you only have time for one change, make it this one. Images are most of a page’s weight and almost always its LCP element. Fixes here give the largest return per hour spent.
| Cause | Typical cost | Fix |
|---|---|---|
| 1. JPEG and PNG instead of AVIF/WebP | 400–1200 ms | Convert; AVIF cuts 50–70% of weight with no visible loss |
| 2. One image size for every screen | 300–900 ms | Serve multiple widths via srcset, a narrower file to phones |
3. Missing width and height | CLS 0.1–0.3 | Set dimensions or aspect-ratio so space is reserved |
4. loading="lazy" above the fold | 200–600 ms | Remove lazy from the LCP image and give it fetchpriority="high" |
The most common specific finding: a 2400-pixel-wide hero shot straight from the photographer, uploaded to the CMS untouched, displayed on a 390-pixel screen. That is 1.8 MB where 90 KB would do. Correct markup looks like this:
<img
src="/img/hero-800.webp"
srcset="/img/hero-400.webp 400w,
/img/hero-800.webp 800w,
/img/hero-1600.webp 1600w"
sizes="(max-width: 768px) 100vw, 800px"
width="800"
height="450"
fetchpriority="high"
alt="The team at work"
/>Fonts and CSS: causes 5–8
Fonts are treacherous because they weigh little but block text from painting. The visitor stares at an empty screen while an 80 KB file downloads, and that counts as a slow page even though the HTML arrived instantly.
- 5. Three families and eight weights. Every weight is a separate 20–60 KB file. You realistically need two: regular and bold. Saving: 150–400 KB and 200–500 ms.
- 6. `font-display: block`, or no value at all. Text stays invisible for up to three seconds.
swappaints a system font immediately and substitutes later, making the page readable a full second earlier. - 7. Unused CSS from a theme or UI framework. A typical theme ships 200–400 KB of styles of which a page uses about 15%. Stripping the unused rules returns 100–300 ms of render time.
- 8. Heavy visual effects on mobile.
backdrop-filter: blur(), layered shadows and infinite animations force the browser to repaint during scroll. On a budget Android this is not measured in load milliseconds — it shows up as visible scroll stutter, which users read as "the site is slow".
<link rel="preload" as="font" type="font/woff2"
href="/fonts/inter-400.woff2" crossorigin>
<style>
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-400.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}
</style>Scripts and widgets: causes 9–12
This is the most awkward category, because somebody added each script for a defensible reason. The trouble starts when there are eight of them. JavaScript does not just download — it executes, and while it executes the page ignores taps.
| What it is | Typical weight | What to do |
|---|---|---|
| 9. Analytics and advertising pixels | 80–250 KB | Keep what you use, load the rest deferred |
| 10. Live chat widget | 150–400 KB | Load after first interaction or a 5-second delay |
| 11. Sliders and animation libraries | 100–300 KB | Replace with CSS wherever the effect is simple |
| 12. Duplicate libraries and legacy jQuery | 90–200 KB | Audit dependencies, delete anything never called |
A rule we apply on every project: no third-party script loads before the user has seen content. The chat appears after five seconds or after a scroll — conversion does not suffer, and INP improves by 100–300 ms. Analytics goes in after the load event, never synchronously in the <head>.
Every widget on a site has an owner and a reason. The problem is that the reason was valid three years ago and the widget still loads today.
Server and delivery: causes 13–15
This part is invisible in the browser but sets the ceiling for everything else. If the server thinks for 900 ms before the first byte, no amount of image optimisation will pull LCP into the green.
- 13. Cheap hosting with no cache. A $3-a-month shared plan produces a TTFB of 600–1200 ms at peak hours. Moving to a proper VPS or managed hosting with full-page caching usually removes 400–800 ms — the cheapest speed gain available.
- 14. No CDN. If your server sits in Germany and half your visitors are on another continent, they pay 150–300 ms for physical distance alone. A CDN for static assets removes almost all of that and costs between nothing and a few dollars a month.
- 15. No compression or cache headers. Brotli or gzip shrink HTML, CSS and JS by 60–80%.
Cache-Controlheaders on static assets mean a returning visitor downloads almost nothing. Both take an hour to configure and apply to the entire site at once.
Fix order, from biggest effect to smallest
- Compression and cache headers on the server — 1 hour, affects every page
- Convert images to AVIF/WebP and add
srcset— 3–6 hours - Remove lazy-loading and add
fetchpriorityon the LCP image — 30 minutes - Cut fonts to two weights and set
font-display: swap— 1 hour - Defer chat, analytics and pixels — 2 hours
- Remove heavy blur effects and animations on mobile — 2–4 hours
- Strip unused CSS and redundant libraries — 4–8 hours
- Change hosting or add a CDN — 1 day
If the site is still slow after all of that, the problem is architectural: a page-builder theme, or a platform that assembles every page from the database on every request. At that point the conversation is about the stack rather than optimisation — we compared the options in Next.js vs WordPress.
Frequently asked questions about site speed
What counts as a good loading speed in 2026?
Use Core Web Vitals as the target: LCP under 2.5 seconds, INP under 200 milliseconds, CLS under 0.1 — all measured on a mobile connection, not a desktop on fibre. Google treats those as the boundary of "good", and they are what real user experience is scored against. Four seconds on mobile already measurably damages conversion.
Does speed genuinely affect Google rankings?
Yes, but less than people assume: speed is one signal among many and mostly acts as a tiebreaker between pages of similar relevance. The stronger effect is indirect — slow pages lose visitors before they see any content. That is why speed work almost always pays back through conversion faster than through position.
Why does my PageSpeed Insights score change on every run?
The lab test runs on a remote machine with an emulated slow device and network, so results naturally fluctuate by around ten points. Rely on the field data at the top of the report instead — it is collected from real visitors’ browsers over the previous 28 days. If no field data appears, the site simply does not have enough traffic yet for it to be generated.
What does speeding up a website cost?
A baseline package — compression, images, fonts, deferred scripts — is typically 8–16 hours of work, or roughly $200–500, and it delivers most of the available gain. Deeper optimisation involving template rewrites or a platform change starts around $1,000 and only makes sense once the basics are exhausted.
Will a caching plugin solve the problem?
Partly: caching removes server-side page generation time and genuinely cuts several hundred milliseconds off TTFB. It does not shrink your images, remove excess JavaScript, or improve INP, because those scripts still execute in the browser. Caching is the first step, not a substitute for front-end optimisation.
In short
- Measure before changing anything, and read LCP, INP and CLS separately rather than one composite score.
- Images give the biggest win: modern formats,
srcset, dimensions in the markup and no lazy-loading above the fold. - Third-party scripts hurt responsiveness rather than load time — defer chat, analytics and pixels until content is visible.
- Blur effects and infinite animations break scroll smoothness on budget phones more than an extra 200 KB ever would.
- Compression, cache headers and decent hosting are an hour of work that applies to the whole site at once.
Related reading
Core Web Vitals Explained: LCP, INP and CLS in Plain English
The three metrics Google uses as a ranking signal. Each one explained, plus what breaks them most often.
Mobile-First Design: Why 70% of Your Traffic Decides Everything
Most of your visitors are on a phone. Most sites are still designed on a 27-inch monitor.
Next.js vs WordPress: Which One Your Business Site Needs
This is not modern versus outdated. It is two different cost models — here is both, without the sales pitch.