PATTERN Cited by 1 source
Conditional animation for scroll performance¶
Pattern¶
Gate UI animations on two conditions — (a) interaction state (only animate when the user is not actively scrolling / interacting) and (b) device class (disable animation entirely on low-end devices) — rather than animating unconditionally. Treat animation as a budget item, not a universal default.
Structure:
show_animation = not actively_scrolling
AND not low_end_device
for element in visible_elements:
if show_animation:
animate(element)
else:
render_static(element)
When to use¶
- The surface is performance-sensitive — infinite scroll, video playback, high-frequency interaction.
- The product supports heterogeneous devices — recent flagships + multi-year-old low-end phones.
- Animation is enhancement — the feature works without it; animation only adds visual delight.
- Baseline scroll fps / playback smoothness is a hard constraint that regresses if any per-frame work is added.
Why gate on scroll state¶
During active scroll, the UI thread is under maximum pressure — layout, compositing, frame rendering, gesture processing all competing. Adding animation-tick work at this moment is the single most common cause of fps regressions. Disabling animation only during scroll gives you the visual delight at rest while protecting scroll fps under load.
Why gate on device class¶
Low-end devices have:
- Limited CPU budget per frame.
- Weaker GPU / compositor.
- Battery budgets that punish continuous animation.
- Users less tolerant of phone warming / drain — often the users for whom the product matters most (e.g. messaging on a multi-year-old phone).
On these devices, even idle animation can compromise performance. Disabling entirely is the graceful degradation.
Canonical wiki reference¶
Meta Friend Bubbles (sources/2026-03-18-meta-friend-bubbles-enhancing-social-discovery-on-facebook-reels):
"We also made animation strictly conditional. During active scrolling and interaction, animation is disabled to preserve scroll responsiveness. On low-end devices where even idle animation could compromise performance, we turn it off entirely. Along with additional optimizations in the underlying method, this approach enabled us to ship friend bubbles while preserving core Reels performance."
Friend Bubbles show avatar bubbles on Reels videos. The feature works without animation — the bubble itself is the signal. Animation is the polish on top. Meta's posture: "animation is strictly conditional" — it's turned off in every case where it costs more than it adds.
Complementary primitives¶
- Prefetch-window metadata co-attending — keep the fetch path cheap by piggybacking on the existing prefetch window.
- Low-end-device inclusion — the broader Meta posture of designing product features to work on the oldest viable device (canonical wiki example from MLow audio codec).
Together these three primitives form the discipline Meta uses when adding new per-video features to Reels: cheap fetch path, conditional animation, low-end graceful degradation. Each closes a distinct failure mode.
Implementation considerations¶
- Detecting "actively scrolling." Usually based on scroll-velocity threshold + debounce. Has to be fast enough to pause animation at scroll start and resume at scroll end without flicker.
- Detecting "low-end device." Multiple signals: device model, year, RAM, GPU tier, recent frame-drop rate, thermal state, battery state. Meta's threshold is not disclosed.
- Thermal + battery signals too. On mid-range devices under thermal pressure, animation off is the right choice temporarily — dynamic gating is better than static device-class gating.
- Graceful fallback matters. The static render must look intentional, not broken. Bubble still appears; just doesn't animate.
- Accessibility parallel. Users with "reduce motion" preferences should be gated the same way — same mechanism, different trigger.
Anti-patterns¶
- Animate unconditionally. Causes scroll fps regressions on flagships under load and battery drain on low-end devices everywhere.
- Gate only on device class. Misses the scroll-state failure mode on flagships.
- Gate only on scroll state. Low-end devices suffer from the idle-animation cost too.
- Treat animation as blocking. If animation is on the critical render path for the feature, the feature breaks when animation is disabled. Animation must be decorative, not load-bearing.
- Assume a device detection API is reliable. Heuristics + runtime perf counters are more robust than static device-class lookups.
Related patterns / concepts¶
- concepts/prefetch-window-metadata-coattending — the fetch-path sibling primitive.
- concepts/low-end-device-inclusion — the overarching posture.
- systems/facebook-reels — the surface where this pattern is canonical.
- systems/meta-friend-bubbles — canonical feature instance.
Seen in¶
- sources/2026-03-18-meta-friend-bubbles-enhancing-social-discovery-on-facebook-reels — canonical; names the two conditions (scroll state + device class) explicitly.