menuclose

What Actually Makes a Website Slow

Almost every slow website we are asked to look at is slow for the same three or four reasons, and they are rarely the reasons the team has been working on. There is usually a great deal of effort going into minifying small files and chasing the last two points of a synthetic score, while a four megabyte hero image loads above the fold and a chat widget blocks the main thread for a second and a half. Performance work pays off when it is ordered by impact, and the order is more predictable than most people expect.

Measure the Right Thing, on the Right Device

Three metrics describe what a visitor actually experiences. Largest Contentful Paint is how long until the main content appears, and good is under 2.5 seconds. Interaction to Next Paint is how quickly the page responds when someone taps or clicks, and good is under 200 milliseconds. Cumulative Layout Shift measures how much the page moves around while loading, and good is under 0.1.

The mistake is measuring them on a workstation over a fast connection. That machine is not your visitor. A mid range Android phone on a congested mobile network is closer to the median experience, and the gap between the two is not small: a page that feels instant on a laptop can take six seconds to become useful on a phone, largely because JavaScript execution is bound by a much slower processor. Field data from real visitors beats lab data from your own browser every time, because the lab cannot reproduce the diversity of what people actually use.

Images Are Almost Always the Largest Win

In practice, images are the single biggest source of wasted bytes on the web, and the waste is usually not subtle. The common pattern is an image stored at the dimensions it came off a camera or out of a design tool, then scaled down in CSS to a fraction of that size. The browser downloads every one of those pixels and throws most of them away. Resizing an image to the largest dimension it is ever displayed at is frequently an eighty percent reduction with no visible difference on any screen.

Beyond raw dimensions, three habits do most of the remaining work. Serve modern formats such as WebP or AVIF where the browser supports them. Set explicit width and height attributes on every image so the browser reserves the correct space before the file arrives, which eliminates a major source of layout shift. Lazy load everything below the fold, and do not lazy load the hero, because deferring the largest contentful element is a direct penalty on the metric you are trying to improve.

Video deserves the same scrutiny. A background video is often the heaviest asset on a page by an order of magnitude. Re-encoding at an appropriate rate factor routinely halves it with no perceptible quality loss, and a poster frame gives the visitor something immediately rather than a black rectangle while the file buffers.

Third Party Scripts Are the Ones You Did Not Write

Chat widgets, tag managers, analytics stacks, A/B testing tools, heat maps, consent frameworks, and social embeds all share a property: they run on your main thread, and you did not write, review, or benchmark any of them. A single chat widget commonly ships more JavaScript than the entire site around it. Tag managers are worse, because they are a delivery mechanism for scripts that nobody audits and that marketing can add without an engineer ever seeing the change.

Each one is also a dependency in the sense we mean on our infrastructure page. Their outage becomes your outage. Their performance regression becomes your performance regression, deployed to your visitors without a release on your side. The correct question for every third party tag is not whether it is useful but whether it is useful enough to justify running someone else's code on every page load, forever. Most sites carry several that fail that test and at least one that nobody can identify.

Render Blocking Is a Sequencing Problem

A browser cannot paint until it has processed the stylesheets in the head, and it cannot continue parsing HTML when it hits a synchronous script. This is why two sites with identical total weight can feel completely different: the order and the blocking behavior matter more than the sum.

The fixes are well understood and rarely applied consistently. Scripts that do not need to run during parsing should carry defer or async. Stylesheets should be as small as the page actually requires, which is a different quantity from what the theme or framework provides. If a site loads six stylesheets because six plugins each brought their own, the problem is not compression, it is that the page is loading six stylesheets. Serving over HTTP/2 or HTTP/3 removes the old penalty for multiple requests, but it does not make unnecessary work free.

Fonts Are a Silent Tax

Web fonts are easy to add and easy to forget. A site loading four weights of two families, in formats older than any browser still in use requires, is carrying several hundred kilobytes to render text that would have looked nearly identical in two weights of one family. Worse, a font that blocks rendering leaves the visitor staring at blank space where the content already exists.

Load only the weights actually used in the design. Set font-display so text renders immediately in a fallback and swaps when the font arrives, rather than hiding content while waiting. Subset to the character ranges the site needs. These are small changes that show up directly in Largest Contentful Paint, because on a text heavy page the largest element is very often a block of text.

Time to First Byte Is a Server Problem

Everything above concerns what happens after the response arrives. If the first byte takes 800 milliseconds, no amount of frontend work will save the page, and this is the failure that frontend audits consistently miss.

Slow first bytes usually mean the server is doing work it should not be doing on every request: querying a database to assemble a page that has not changed in weeks, rendering templates for anonymous visitors, or waking an application runtime that could have been bypassed entirely. A cache in front of the application answers in a fraction of a millisecond without touching it, and a page compiled to a static file answers faster still. That decision is covered in more detail in Most Marketing Websites Do Not Need a CMS.

Geography matters as well. A visitor on another continent pays the round trip regardless of how fast the origin is, which is what a content delivery network exists to solve for static assets.

What Matters Less Than People Think

Some of the most common performance work produces almost nothing. Minifying a file that is already two kilobytes saves a rounding error. Chasing a synthetic score from 98 to 100 while the site takes five seconds on a real phone optimizes the measurement rather than the experience. Rewriting a component in a faster framework is irrelevant when the bottleneck is a five megabyte image and three analytics vendors.

The discipline is to measure first, fix the largest item, and measure again. Performance work done in that order tends to finish quickly, because the distribution is lopsided. A handful of problems usually account for most of the loss.

Speed Is an Architecture Decision

Sites that are fast are generally not fast because someone optimized them at the end. They are fast because the decisions that determine performance were made correctly at the start: what the page loads, who serves it, how much code runs, and how many organizations are involved in delivering it. Optimization can recover a great deal, but it cannot undo an architecture that requires a database query, a template render, and eleven third party scripts to display a paragraph of text.

That is why we treat speed and user experience as an engineering property rather than a cleanup task, and why the systems we build serve most requests without waking an application at all.

If your site is slow and the work so far has not moved it, we can tell you which three things are actually costing you the time. Contact us and we will take a look.