Why Does My Animation Stutter on Mobile?
Diagnose and fix dropped frames and jank in mobile animations: layout reflows, paint storms, garbage collection, and GPU layer promotion.
Core Takeaway
Mobile animation stutter is almost always caused by animating properties that trigger layout recalculation (such as width, height, top, or left) or paint invalidation (such as box-shadow or border-radius). To achieve butter-smooth 60 or 120 FPS, animate exclusively transform (translate3d, scale, rotate) and opacity, and promote animating elements to their own GPU compositing layer using will-change: transform.
The browser rendering pipeline on mobile processors
A browser renders frames through four stages: JavaScript execution, Style calculation, Layout, Paint, and Composite. Desktop processors can often power through layout calculations on every frame. Mobile chips (especially low- and mid-tier Android devices) immediately drop frames when forced to recalculate layout or repaint surfaces during motion.
The golden rule: composite-only properties
Only two CSS properties bypass layout and paint entirely on the GPU: transform and opacity. Animating height to collapse an accordion forces the browser to recalculate the positions of every element below it on every single frame.
- Never animate width, height, margin, padding, top, or left
- Replace height collapse with transform: scaleY() or FLIP techniques
- Promote elements to GPU layers using will-change: transform (and remove on finish)
- Avoid blurring or animating heavy box-shadows on mobile
Garbage collection and JavaScript thread bottlenecks
JavaScript libraries that allocate new objects, closures, or vectors on every frame trigger the garbage collector (GC). When GC kicks in on a mobile CPU, execution pauses for 20-50ms, causing an immediate visual hitch. Modern animation engines avoid frame allocations.
DevicePixelRatio and canvas bottlenecks
Mobile screens feature high pixel densities (2x, 3x, or 4x Retina). Rendering complex Canvas or WebGL animations at full uncompressed canvas buffers without throttling can saturate memory bandwidth and overheat mobile GPUs.
Key Principles to Remember
- Stick strictly to transform and opacity for all continuous UI motion
- Use Chrome DevTools Performance panel CPU throttling to profile on low-end hardware
- Avoid object allocations inside requestAnimationFrame to eliminate GC pauses
- Remove will-change hints once the animation concludes to free VRAM
Frequently Asked Questions
Sources
- Rendering Performance — Google Web Fundamentals
- CSS Triggers (Layout, Paint, Composite) — Paul Irish / Google