Why your website is slow — and what it costs you
The five causes behind almost every slow site, how to find yours in ten minutes, and why one design decision can cost you 1.9 seconds without anyone noticing.
This article was translated from Danish. Read the original.
Speed is not a technical detail you can deal with later. Google measures it directly and uses it in ranking, and visitors leave pages that don’t appear.
The good news is that almost every slow site fails on the same five things. Here they are — and how to find yours.
Measure first, never guess
Open PageSpeed Insights, enter your address and choose mobile.
The number that matters most is LCP (Largest Contentful Paint): the time until the largest element on screen is visible. Google’s threshold is 2.5 seconds. Above that, you lose both visitors and rankings.
Two other numbers are worth looking at: CLS (does the content jump around while the page loads?) and INP (how long does it take to respond when somebody taps?).
Run the test in an incognito tab with no extensions. Otherwise you are measuring your own browser extensions.
Cause 1: The images
By far the most common. A photo straight from a camera is 4–8 MB. The same image in the right format and the right size is 80–200 kB.
Three things to do:
- Convert to WebP. Typically 30–50% smaller than JPEG at the same quality. We saved 439 kB in a single pass over our own site.
- Scale to the size shown. An image displayed at 600 px wide should not be 3,000 px wide.
- Put
loading="lazy"on everything below the fold. Then the images are only fetched when somebody scrolls down to them.
This alone solves a significant share of cases.
Cause 2: Too much JavaScript
Chat widgets, cookie banners, analytics tools, carousels, animation libraries. Individually they are small. Together they are often 1–2 MB that has to be downloaded, parsed and run before anything can be used.
Open the network tab in developer tools and sort by size. Go down the list and ask of each one: does this bring me customers?
Chat widgets are the worst. A typical chat solution costs 400–900 kB. If it isn’t bringing you enquiries you wouldn’t otherwise have had, you are paying in rankings for nothing.
Cause 3: Fonts fetched from elsewhere
Google Fonts loaded from Google’s servers requires a lookup to a foreign domain before the text can be drawn. On mobile that typically costs 200–500 ms.
The fix is to host the fonts yourself, as woff2, ideally as variable fonts in a Latin subset.
And use font-display: swap, so the text is visible immediately instead of waiting.
Cause 4: Your animation IS your LCP
This is the one that surprises even people in the industry, and we fell into it ourselves.
Many sites have entrance animations: elements start at opacity: 0 and fade in as you scroll. It
looks good. But if your hero image or your headline starts out invisible and only fades in after a
delay — then that is your LCP moment.
We have measured a site where 1.9 of a 3.5-second LCP was pure design decision. The network had finished long before. The element had simply been made invisible on purpose.
An important detail: a session-based “only show the animation the first time” approach doesn’t help. A measurement always starts in an empty profile and therefore always sees the animation.
Find the LCP element by area above the fold, and work out when it becomes visible from the CSS — not from the network tab.
Cause 5: The server is slow
If more than 600 ms passes before the first byte arrives, the problem is on the server.
On WordPress that almost always means either cheap shared hosting or too many plugins that have to run on every request. Caching helps a lot. Better hosting helps more.
A static site doesn’t have the problem — there is nothing to generate, the file already exists.
What slowness costs
Two things, both measurable:
Rankings. Google uses Core Web Vitals as a ranking factor. With otherwise equal content, the faster page wins.
Conversions. People leave pages that don’t respond. On mobile, where the connection is worse and patience is shorter, the effect is largest. Your own analytics can show it: compare the bounce rate on mobile and desktop. If there is a big difference, speed is a likely part of the explanation.
How to make it better — in order
- Compress images. Biggest effect, least work.
- Remove the JavaScript you don’t use. Be ruthless. Widgets that don’t produce enquiries: out.
- Host fonts yourself. An hour’s work, 200–500 ms back.
- Remove delays on anything visible from the start. Animate everything below the fold by all means.
- Put
fetchpriority="high"on the LCP image. Then the browser fetches it first. - Turn caching on. Static files with a hash in the name can be cached for a year.
- Load third-party content when somebody scrolls to it. Not at page load.
A warning about compression
One specific trap we fell into ourselves: never turn on compression for video in the proxy layer.
Both Traefik and Caddy can be set to gzip everything without filtering on file type. Then .mp4
and .webm get compressed too — and Chrome cannot play a video source with
Content-Encoding: gzip, while Safari loses the support for partial downloads it requires to
start at all.
The result is a video that doesn’t work for anyone, without a single error message anywhere. The gain in our case was 620 bytes out of 1.1 MB.
Check it with:
curl -sI -H "Accept-Encoding: gzip" https://yourdomain.dk/video/film.webm
It should say accept-ranges: bytes and have no content-encoding.
Frequently asked questions
What counts as good speed? LCP under 2.5 seconds on mobile, and a total page size under 1 MB. Under 500 kB is good.
Do I need 100 in PageSpeed? No. Above 90 on mobile is fine. The last few points often cost more than they give.
Can a WordPress site be fast? Yes, with caching, few plugins and decent hosting. It just requires sustained discipline. See WordPress or custom-built.
Does removing the cookie banner help? If you have nothing that requires consent, you don’t need a banner. Cookie-free analytics exist and measure perfectly well. It is both faster and better for conversion.
Why us
Cheaper than most, and not worse for it
We are three developers. No project managers, no salespeople, no open-plan office downtown. That overhead is what you would otherwise be paying on top of the work itself, and it is why we can keep the price down on websites, webshops, web apps and mobile apps alike. Every price is published and fixed in writing before we start — from DKK 375 a month or DKK 3,995 one-time. See prices.
Cheaper does not mean less. We build and run our own products: NBS Booking, NBS Food and the KalorieTracker app, which is live in the App Store and Google Play. So we have already paid for the mistakes we advise you about. You talk to the person writing the code, and you own the code afterwards. If you want to move on without us, you can.
