Testing Animations on Low-End Devices

Part of Frame Budgeting & 16ms Targets in Performance Budgeting & GPU Architecture.

The problem

Every animation on the site is smooth on the team’s laptops and recent phones. Field data says a fifth of interactions on mid-range Android devices show late frames, and support receives complaints about “the menu being slow” that nobody can reproduce. Buying one cheap phone helps, but it is one device, it lives in a drawer, and its behaviour when warm is different from its behaviour after a cold boot.

Reproducing low-end conditions reliably is a process, not a device.

Root cause analysis: three different limits

Low-end devices are not simply “slower”. Three separate constraints produce different symptoms.

Main-thread speed. Slower cores make every style recalculation, layout and paint take longer, so work that fitted in 16ms on a laptop overruns. CPU throttling in the Performance panel models this well: 4x slowdown approximates a mid-range phone and 6x a low-end one, relative to a modern laptop.

GPU and memory. Cheap GPUs have less memory and slower texture upload. Symptoms are stuttering at the start of animations while textures upload, and flicker when layers are evicted and re-rastered, as described in texture memory budget for mobile. CPU throttling does not simulate this at all.

Thermal and power state. Phones downclock when warm or on low battery, and browsers reduce frame rates in low-power modes. An animation that is smooth on a cold device can drop frames after five minutes of use. No emulation reproduces this; only real hardware does.

Emulation gets you most of the way. DevTools device emulation sets a viewport and user agent but does not slow the device. Combining it with CPU throttling, network throttling and a deviceMemory override covers most main-thread problems, which are the majority.

What each testing method can showThrottling finds main-thread problems; only real devices show GPU and thermal behaviour.What each testing method can showMain-thread costTexture upload / evictionThermal throttlingCPU throttling4x-6xYesNoNoDevice emulationaloneNoNoNoRemote-debuggedlow-end phoneYesYesWith sustained useField measurementYes, aggregatedIndirectlyYes
Throttling finds main-thread problems; only real devices show GPU and thermal behaviour.

Step-by-step resolution

A repeatable low-end test passThrottled desktop for iteration, real hardware for confirmation.A repeatable low-end test pass1Choose a target device from analytics, with its memory and core count.A concrete target2Iterate with 4x or 6x CPU throttling and a small viewport.Fast feedback on main-thread cost3Check the Layers panel for texture memory at the same time.Catches GPU problems throttling hides4Confirm on a real low-end phone over remote debugging.Upload, eviction and thermal reality5Repeat the interaction after several minutes of use.Warm-device behaviour6Record which animations degrade and at what level.
Throttled desktop for iteration, real hardware for confirmation.

Production code pattern

// A quick capability signal for progressive motion enhancement.
const lowPower =
  (navigator.deviceMemory ?? 8) <= 4 ||
  (navigator.hardwareConcurrency ?? 8) <= 4 ||
  matchMedia('(update: slow)').matches;

document.documentElement.toggleAttribute('data-low-power', lowPower);
/* Heavier effects are opt-out on constrained devices. */
[data-low-power] .card { backdrop-filter: none; }
[data-low-power] .hero__parallax { animation: none; }
[data-low-power] .list__item { animation-delay: 0ms !important; }   /* no long staggers */

/* prefers-reduced-motion is a user choice and always wins. */
@media (prefers-reduced-motion: reduce) {
  .card, .hero__parallax, .list__item { animation: none; transition: none; }
}
// Playwright: run the animation suite under throttling for CI or local checks.
const client = await page.context().newCDPSession(page);
await client.send('Emulation.setCPUThrottlingRate', { rate: 6 });
await page.emulateMedia({ reducedMotion: 'no-preference' });
await page.setViewportSize({ width: 390, height: 844 });

Rendering Impact: none from the test tooling. The data-low-power attribute reduces work on constrained devices by removing the most expensive effects, which is a design decision as much as a performance one.

Device capability signals are coarse. deviceMemory is rounded and capped, hardwareConcurrency says nothing about core quality, and neither reflects thermal state. Treat them as a hint for removing expensive decoration, never as a reason to remove functionality, and never as a substitute for prefers-reduced-motion, which expresses a user’s choice rather than a device’s capability.

Longest animation frame during the same menu interactionOne codebase across four conditions.Longest animation frame during the same menu interactionLaptop, no throttling18 msLaptop, 4x CPU throttle62 msLaptop, 6x CPU throttle94 msLow-end phone, cold88 msLow-end phone, warm151 ms
One codebase across four conditions.

Building a small device lab

Two or three physical devices cover most needs: a low-end Android phone bought new in the last two or three years, an older iPhone still receiving updates, and a mid-range tablet if tablets are significant in analytics. Keep them charged but not always plugged in, since charging affects thermal behaviour, and keep them on the same operating system versions your users have rather than the newest beta.

Remote debugging is what makes them usable: Chrome’s device inspection for Android and Safari’s Web Inspector for iOS both attach a full Performance panel to the real device, so traces come from the hardware rather than an approximation. Run the same scripted interactions used for CI budgets so numbers are comparable.

Verification checklist

Constraints and trade-offs

  • CPU throttling slows script, style and layout, but not GPU work or texture upload.
  • deviceMemory and hardwareConcurrency are coarse and can mislead on unusual hardware.
  • Physical devices need maintenance: charging, updates and occasional replacement.
  • Testing warm devices is slow, so reserve it for release candidates.
  • Removing effects for low-power devices creates a second experience to design and review.

Frequently asked questions

Does CPU throttling simulate a low-end phone?

For main-thread work, approximately: 4x resembles a mid-range phone and 6x a low-end one. It does not simulate GPU speed, texture memory or thermal throttling.

Is device emulation in DevTools enough?

No. It changes viewport and user agent but does not slow anything down. Combine it with CPU throttling, and confirm on real hardware.

Should I disable animations on low-end devices?

Remove expensive decoration such as blur and parallax, and keep functional motion. Never use device hints as a substitute for the user’s reduced-motion preference.

Why is my phone slower after a few minutes of testing?

Thermal throttling. Devices downclock when warm, which is also what users experience during real sessions, so test warm as well as cold.