REDLINE
← All guidesDiagnosis · 10 min read

Why your site is fast on your laptop and slow on a phone

The hardware gap, thermal throttling, network variance and cache warmth that make developer machines a misleading place to judge performance.

Almost every performance complaint starts the same way: the team cannot reproduce it. The page loads in under a second on the developer's machine, the staging environment looks fine, and yet support keeps receiving screenshots of a spinner. The reason is rarely mysterious. Development happens on the fastest hardware, the warmest cache and the best network in the organisation, and every one of those three things hides a different class of problem.

The hardware gap is larger than it feels

Developer machines are outliers. A current laptop has a large power budget, active cooling, fast storage and memory measured in tens of gigabytes. A mid-range phone that is three years old has a fraction of the single-core throughput, no fan, thermal limits that engage within seconds, and memory pressure that starts far earlier.

For JavaScript specifically the gap is brutal, because most of the work is single-threaded. A script that parses and executes in 120 milliseconds on a laptop can take 600 to 900 milliseconds on a mid-range phone. That is not a rounding error — it is the difference between a page that feels instant and one that feels broken. And the phone still has to decode images, lay out the document and paint, using the same constrained cores.

A useful mental multiplier

When estimating how a change will land on a mid-range phone, assume main-thread work costs roughly four to six times what it costs on your machine, and that anything triggering layout or compositing costs more than that. Then verify, because the multiplier varies by device and by workload.

Thermal throttling: the invisible second device

Phones are designed to run fast in bursts and then slow down to stay cool. The first few seconds after you pick up a cool device are the best performance it will ever show you. Under sustained load — a long scroll, a video, a heavy single-page app — clock speeds drop and stay down.

This matters for testing because it means a quick check on a cold phone is optimistic by design. If your application is used for more than a minute at a time, measure it after a minute of use, not at the moment it opens. Measure the same way twice and you will often find the second reading is the honest one.

Battery saver changes the machine

Low-power modes cap clock speeds, reduce background activity and sometimes throttle animations at the system level. A meaningful share of real users are in this state most of the time, especially in the evening. A device at 15% battery is not the device you benchmarked.

Your network is not their network

Office and home broadband on a wired or strong Wi-Fi connection has low, stable latency. Mobile networks have variable latency, lossy periods, and dramatic differences between a good signal and a weak one. Bandwidth is usually not the problem; jitter and round trips are.

Cache warmth hides the first visit

By the time you test a feature, you have loaded the page dozens of times. The bundle is cached, the fonts are cached, the API responses may be cached, the service worker is installed and the database connection is warm. A first-time visitor on a phone has none of that.

The fix is procedural rather than technical: measure a cold load deliberately. A fresh profile or a private window, cache disabled, and — if you can — a throttled connection. Whatever number you get there is the number a new user experiences, and new users are the ones who decide whether to come back.

The shape of the difference, subsystem by subsystem

CPU-bound work

Hydration, large component trees, date and number formatting in loops, client-side sorting and filtering of big lists, and anything that runs on every keystroke. On a laptop these disappear into the noise. On a phone they are the whole budget.

Memory-bound work

Holding decoded images, unbounded caches and very long lists in memory. A laptop absorbs it; a phone starts collecting garbage mid-interaction, which the user reads as stutter.

GPU-bound work

Backdrop filters, large shadows, stacked transparency, full-screen gradients and continuous animation. These are nearly free on discrete graphics and expensive on a phone compositing at high resolution.

Layout-bound work

Reading geometry and writing styles in the same frame, animating properties that trigger layout, and deep trees that must be reflowed as a unit. The cost scales with tree size, and phones pay it at a lower clock speed.

How to test honestly without a device lab

What to do first when you cannot reproduce a complaint

Start by establishing whether the device or the page is the constraint. Benchmark the device class the complaint came from; if the hardware itself scores poorly, your target is main-thread and compositing work rather than payload size. If the device scores fine, the problem is in what the page does — usually too many round trips, too much JavaScript before first interaction, or a third party blocking rendering.

Once you know which side the constraint sits on, the ordered remedies in the page-load checklist apply directly, and reading a device performance score explains how to interpret the benchmark you just took.

Keep reading