A practical checklist for fixing slow page loads
An ordered checklist for making a page load faster, with the realistic gain and the cost of each step so you can stop at the right point.
Most performance work fails not because the team picks the wrong fixes, but because it picks them in the wrong order. Image compression is satisfying and measurable; it is also pointless while a render-blocking third-party script sits in the head. This checklist is ordered by the ratio of gain to effort on a typical content or application page, with an honest note on what each step actually buys you and when to skip it.
Before you start
1. Remove render-blocking work in the head
Anything synchronous in the head delays the first pixel. Synchronous third-party scripts — tag managers, consent tools, chat widgets, A/B testing snippets — are the single most common cause of a slow first paint, and they are usually the easiest to move.
- Load analytics and marketing scripts with defer or async, or after the page is interactive.
- Inline only the critical CSS a first screen needs and load the rest normally.
- A/B testing tools that hide the page until they decide what to show are a deliberate trade of speed for experiment fidelity. Make that trade consciously, and cap how long they may block.
Typical gain: several hundred milliseconds to multiple seconds on mobile. Cost: low, mostly coordination with whoever owns the tags.
2. Cut the number of round trips before first paint
On a high-latency connection the count of dependent requests matters more than their size. A page that needs HTML, then CSS, then a font, then a script, then an API call before anything renders has serialised four network waits.
- Preconnect to the origins the critical path genuinely needs, and only those.
- Preload the fonts and hero image the first screen depends on.
- Collapse chains: avoid CSS that imports CSS, or scripts that fetch scripts.
- Render meaningful HTML from the server so the first paint does not wait on a data request.
Typical gain: 200-800 ms on mobile networks. Cost: low to moderate.
3. Fix the largest element on the first screen
Usually a hero image, a banner or a headline blocked by a font. The user's sense of "the page loaded" is tied almost entirely to this one element.
- Serve the hero image in a modern format, correctly sized for the viewport, and never lazy-load it — lazy loading the largest visible element delays it on purpose.
- Give images explicit width and height, or an aspect ratio, so nothing jumps when they arrive.
- Use font-display: swap so text is readable immediately, and subset fonts to the characters you need.
- If the hero is rendered by client-side JavaScript, that is the problem to fix, not the image.
Typical gain: the largest single improvement to perceived speed on most content pages. Cost: low.
4. Reduce the JavaScript that runs before interaction
Bytes matter, but execution matters more: a phone pays to download, parse, compile and run. This is where the developer-machine illusion is strongest, because parsing is nearly free on a laptop.
- Split bundles by route so a landing page does not ship the code for a dashboard.
- Defer components that are below the fold or behind an interaction.
- Audit dependencies by cost, not by count — one date or charting library can outweigh everything else.
- Prefer server rendering or static generation for content that does not change per user.
- Break long tasks into chunks that yield, so input is handled between them instead of after them.
Typical gain: the dominant factor in interaction latency on mid-range phones. Cost: moderate to high, and the most likely step to need real engineering time.
5. Take the third parties seriously
Third-party code is the part of the page you did not write, cannot profile easily and do not control the release schedule of. It is also frequently half the page weight.
- List every third-party origin the page contacts and name the business owner of each. Anything without an owner can usually go.
- Load chat, support and survey widgets on interaction rather than on load.
- Set a budget for third-party origins and enforce it in CI, because these creep back in through marketing tooling rather than through code review.
Typical gain: large and durable. Cost: political more than technical.
6. Make caching do the second visit for you
- Long-lived immutable caching for fingerprinted assets; short or revalidated caching for HTML.
- A CDN in front of static assets, with sensible compression negotiated at the edge.
- Cache API responses that are not user-specific, and set a revalidation strategy you can explain.
Typical gain: near-instant repeat visits. Cost: low, but mistakes here are visible, so be deliberate about invalidation.
7. Shorten server response time
Time to first byte sets the floor for everything else. If the server takes 900 ms to answer, no amount of frontend work produces a fast page.
- Profile the slowest endpoint on the critical path and fix the query behind it — missing indexes and N+1 queries account for most of it.
- Move rendering closer to users where latency to the origin dominates.
- Cache expensive computed responses rather than recomputing them per request.
8. Only now, micro-optimise
Re-render counts, memoisation, shaving kilobytes off a utility, tuning animation curves. These are real improvements and they belong last, because each costs engineering attention and returns far less than the earlier steps.
Knowing when to stop
Performance work has diminishing returns, and past a point the honest answer is that the page is fast enough and the time belongs elsewhere. Stop when the slowest supported device loads the first screen in a time you would accept yourself, interaction feels immediate on that device, and you have a budget in CI that prevents the gains from eroding.
Make it stick
For deciding which of these steps matters most on your hardware, start from how to read a device performance score, and see Core Web Vitals in plain English for how these fixes map onto the metrics search engines report.
Keep reading
Reading a device performance score
What the CPU, memory, layout, GPU and network numbers in a device benchmark actually mean, and how to tell a real problem from normal variance.
DiagnosisFast on your laptop, slow on a phone
The hardware gap, thermal throttling, network variance and cache warmth that make developer machines a misleading place to judge performance.
MethodLoad testing vs real-device testing
What server-side load tools like k6 and JMeter measure, what they structurally cannot see, and when you need device-side measurement instead.
MetricsCore Web Vitals in plain English
LCP, INP and CLS explained without jargon: what each one measures, what usually breaks it, and the change that most often moves it.