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.
Step-by-step resolution
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-powerattribute 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.
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.
deviceMemoryandhardwareConcurrencyare 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.
Related
- Frame Budgeting & 16ms Targets — the budgets being tested against
- Texture Memory Budget for Mobile — the GPU limits throttling cannot show
- Measuring Dropped Frames in Production — confirming fixes with real users