befound.labsWhatsApp
← Writing
Web··5 min read

Two seconds is a budget, not a wish

Why most small business websites are slow, why the usual advice doesn't fix it, and how to spend a page-load budget on purpose.

A decor studio in Bengaluru showed me their site on their own phone, in their own shop, on their own network. It took nine seconds to show anything at all. They had paid for it eighteen months earlier and had no idea — because the person who built it had only ever seen it on a laptop, on office fibre, with everything already cached.

That's the whole problem in one sentence. Site speed is not a property of a website. It's a property of a website plus a device plus a network, and the people who build sites are systematically testing on the best of all three.

Where the seconds actually go

When I look at a slow small-business site, it's the same four things in roughly the same proportions, every time.

Images at the wrong size. A hero shipped at 4032 pixels wide because that's what the phone camera produced, displayed in a slot 390 pixels wide. That's a 4 MB download to paint an area that needed 180 KB. It's usually more than half the page weight, and it's the single easiest thing to fix.

Fonts that block the paint. A stylesheet from a font host is a render-blocking request to a third-party domain: DNS, TLS, the CSS, and only then the font files. On a good connection that's 200 ms. On a congested mobile network it's a second and a half of blank screen. Not slow — blank, which is worse, because a blank screen is indistinguishable from a broken one.

A megabyte of JavaScript to render text. A page that is a heading, some photographs, a price list and a phone number does not need a framework runtime, a carousel library, an animation library and three tracking scripts. But that's what a theme ships, because the theme has to support everyone.

Third-party scripts. Chat widgets, analytics, pixels, a review embed. Each is a separate connection to a separate domain, each can block, and none of them are on your uptime.

The budget

The useful reframe is to treat the load as a fixed amount of money you're spending, and decide in advance what you're buying.

For a local business site on a mid-range Android over 4G, I work to roughly this:

  • Under 200 KB of what's needed to paint the first screen
  • Under 100 KB of JavaScript, compressed, on first load
  • One render-blocking request, and preferably zero
  • Largest Contentful Paint under 2 seconds on that device, on that network

Those aren't aspirational numbers. They're comfortable if you decide them at the start and uncomfortable to retrofit — which is the real argument for treating it as a budget. Every request is then a question with an answer: what am I removing to pay for this?

What actually moves it

Find the LCP element, then fix that one thing. Largest Contentful Paint is almost always a single element — usually the hero image, sometimes the headline. Everything else you might optimise is noise until that element is fast. Modern formats, correctly sized, fetchpriority="high", and never lazy-loaded, because lazy-loading the thing the metric measures is a well-travelled way to make your score worse.

Give every image explicit dimensions. Not for speed — for stability. A page that reflows as photographs arrive scores badly on layout shift and, more to the point, feels broken to hold. Width and height attributes, or an aspect-ratio box.

Make fonts non-blocking. font-display: swap so text paints immediately in a fallback and swaps when the webfont lands. preconnect to the font host so the connection is warm before the request. And pick a fallback with similar metrics so the swap doesn't visibly jump. Self-hosting the font removes an entire domain from the critical path and is worth it when you can.

Ship less JavaScript. Most of a local business site is text and pictures that never change after render. That should arrive as HTML. The parts that genuinely need to be interactive — a gallery lightbox, a booking form, a chat widget — are islands, and they can load after the page is usable.

Load third parties late, or not at all. A chat widget mounted on click rather than on load costs nothing until someone wants it.

Measure on the right machine

This is the part that gets skipped and it invalidates everything else.

Your laptop is not the test. Test in the browser's device emulation with CPU throttled 4× and the network set to Fast 3G, and then — because emulation is optimistic about CPU — on a real mid-range Android phone. The gap between a flagship and a ₹12,000 handset is not 20%. It is several times, and it lands hardest on JavaScript execution, which is precisely what a theme-built site has most of.

Lab numbers tell you what to fix. Field data from real visitors tells you whether you fixed it. You want both, and if you only get one, take the field data.

Why any of this matters commercially

The usual argument is that Google uses page experience as a ranking signal, which is true and is the least interesting reason.

The interesting one: on a phone, on mobile data, a person deciding whether to enquire about a birthday decoration has approximately no patience, and a blank screen at three seconds reads as this business is not going to be organised. They go back and tap the next result. You never see it — there's no line in any analytics dashboard for people who left before your analytics loaded.

That's the actual cost, and it's why the two-second budget is a business number rather than an engineering one.

Speed isn't a feature you add at the end. It's a series of things you decline to add throughout.

Every site I build gets measured on a throttled phone before it's handed over, and the number goes in the handover document. If it can't be measured it isn't a promise, it's a hope.

Who wrote this

Varun Prakash, an AI engineer in Bengaluru. I build retrieval and agent systems for a US healthcare group and a development-finance investor, and I build websites and booking assistants for local businesses under befound.labs. More on the systems side.