Long Animation Frames
LoAF is a browser timing API reporting frames whose duration exceeds 50ms with attribution to scripts, style, layout, and rendering stages, exposing what froze interaction.
Definition
The Long Animation Frame Timing API reports frames that overrun a 50-millisecond threshold, with structured attribution: which scripts contributed, their source position, and how time split across style, layout, paint, and script execution. It supersedes long-task reporting by covering the whole frame pipeline rather than isolated tasks.
Context and scope
Used to diagnose INP regressions, find main-thread culprits in production via RUM, and attribute jank to specific bundles or third-party scripts.
Common misconceptions
- Long tasks and long frames measure the same thing — a frame can overrun through layout and paint with tiny tasks, which long tasks miss entirely
- Only JavaScript causes long frames — style recalculation, layout, and decode work count too
- A 50ms frame is always user-visible jank — it is a diagnostic threshold for interaction latency budgets, not a perceptibility verdict
Anti-patterns
- Treating a long frame whose culprit is layout as a script optimization problem
- Sampling LoAF entries without source attribution and filing unverifiable performance bugs
- Aggregating frame durations into averages and hiding the tail frames that actually break interactions
Related concepts
Related examples
Authoritative source
What it is
Users feel interaction latency at frame granularity: the click means nothing until the next presented frame. LoAF reports each frame over 50 milliseconds with a breakdown of where the time went and which scripts were involved, turning jank from a vibe into attributable data.
How it works
A PerformanceObserver of type long-animation-frame receives entries carrying startTime, duration, and a list of script attribution records with invoker details and source character positions. Rendering stage durations separate style, layout, paint, and commit. Combined with element timing, teams can trace a slow frame back to a concrete function.
When to use it
Production RUM for INP optimization, regression triage after releases, and audits of third-party impact. Route the entries into your telemetry pipeline with sampling, since frames are high-volume events and attribution payloads are large.
Pitfalls
Attribution names bundles, not intentions: a minified chunk still needs source maps to become actionable. Frames straddling interaction boundaries can double-count; correlate with event timing entries. Older browsers report only long tasks, so pipelines need both entry types.