MonkeyLoader All articles
Performance

The Two-Second Illusion: Making Council Pages Feel Quick on a Wobbly Connection

MonkeyLoader
The Two-Second Illusion: Making Council Pages Feel Quick on a Wobbly Connection

Photo: Rawpixel.com, CC0, via Wikimedia Commons

Council websites have a thankless job. On the same Tuesday afternoon, one visitor is booking a bulky waste collection from a stairwell with two bars of signal, another is renewing a licence on a work laptop that predates the pandemic, and a third is running a screen reader against a page that has just re-rendered for the fourth time. All three of them are judging you by the same measure: does this feel like it's working?

Most councils answer that question with a spinner. It is the cheapest possible answer and one of the least useful.

A spinner is an admission, not an update

Think about what a spinning circle actually communicates: something is happening, we're not telling you what, and we have no idea when it will stop. That's not feedback. That's a shrug rendered in CSS.

There's a well-worn bit of research behind this — people consistently rate a wait as shorter when they can see progress moving than when they can't, even when the clock says otherwise. The load-bearing part isn't the animation, it's the information. Three seconds behind a spinner feels longer than five seconds behind a labelled progress bar, because only one of those gives you a reason to stay.

The irony is that most of the slow moments on a council site aren't slow at all. A planning application lookup that takes 900ms behind a blank white panel will be described as broken. The same lookup at 900ms, with the result table's outline already on screen and the heading already in place, gets described as fast. Nothing changed in the back end. Everything changed in the perception.

Skeletons work — in narrow, specific circumstances

Skeleton screens have become the default answer to this problem, and like most defaults they get misapplied.

They earn their keep when the shape of what's coming is genuinely predictable: a list of library opening hours, a table of planning applications, a grid of school term dates. The visitor sees the container before the contents, and when the contents land there's no jolt.

They backfire badly in three situations:

Two housekeeping notes. Mark skeletons aria-hidden="true" — they're decorative, and screen reader users shouldn't hear a list of empty divs. And keep the contrast low but not invisible; a skeleton at 1.1:1 against the background just reads as a rendering bug.

Tell people where they are, not just that they're waiting

Some of the highest-anxiety journeys on a council site involve a wait with no visible progress: submitting a form, generating a permit PDF, uploading evidence for a housing case. A spinner here is genuinely unhelpful, because the resident has no idea whether their submission survived.

Name the stages. "Checking your details" becomes "Reserving your slot" becomes "Sending your confirmation". You're not inventing progress you don't have — you're reporting the steps your backend is already taking, which your developers almost certainly know about and nobody has written down.

For anything over a few seconds, set an honest expectation: this usually takes about twenty seconds. British users in particular will wait patiently if you've told them what to expect, and will phone the contact centre if you haven't.

Accessible status without the karaoke

WCAG 2.1's Success Criterion 4.1.3 (Status Messages) is where most spinner implementations quietly fail. The pattern that works:

<div id="results" aria-busy="true">
  <p role="status" class="status">Checking availability…</p>
  <ul class="skeleton" aria-hidden="true">…</ul>
</div>

A few rules of thumb that save a lot of pain:

The bandwidth reality nobody budgets for

Perceived performance on a council site is mostly a story about what you ship before the useful bit. A 280KB page with one well-sized image will feel instantaneous next to a 1.8MB page whose hero photograph is a drone shot of the civic centre.

Practical reductions that cost almost nothing:

You can't fix a slow API with CSS, and you shouldn't try. But you can stop a slow API from feeling like a broken site.

Testing this with five people and a stopwatch

You don't need a research budget. You need a throttled connection and twenty minutes.

  1. Throttle in DevTools. Slow 4G preset, 4× CPU slowdown. Record the page load in the Performance panel and note three numbers: when the main heading appears, when the first interactive control becomes usable, and whether anything shifts after the one-second mark.
  2. Run the five-person think-aloud. Grab five colleagues from outside the web team, give them a real task ("find out when your bins are collected"), throttle the connection, and ask them to narrate. Note where they sigh, where they re-click, where they say "is it doing anything?". That's your priority list, in order.
  3. Compare two versions. Serve the spinner variant and the skeleton variant behind a query parameter, alternate between them for a week, and compare task completion time in your analytics. Keep it simple enough that you don't need a statistician.
  4. Watch real user metrics by connection type. Core Web Vitals segmented by navigator.connection.effectiveType will tell you whether your 3G visitors are a rounding error or a third of your traffic. On council sites, it's usually much higher than the team expects.
  5. Don't trust a Lighthouse score on your laptop. It's a lab test on a fast machine over a fast connection. It tells you about your code, not about the person in the stairwell.

The checklist before you ship

The goal was never to make the backend instantaneous. It's to stop making people guess — and a rotating circle has never once answered a question.

Next up in this series: measuring interaction latency on form-heavy pages without a full RUM rollout.

All Articles

Related Articles

Peak Season With Two Pairs of Hands: A Loader Checklist for Small UK Retail Teams

Peak Season With Two Pairs of Hands: A Loader Checklist for Small UK Retail Teams

Cron, Clocks and the Missing Hour: Scheduling Loaders for Europe/London

Cron, Clocks and the Missing Hour: Scheduling Loaders for Europe/London

Your Bundle Is Too Big: Splitting a UK SaaS Front-End by Route Without a Framework Rewrite

Your Bundle Is Too Big: Splitting a UK SaaS Front-End by Route Without a Framework Rewrite