Diagnosing INP Regressions via the LoAF API
Long Animation Frames API entries expose script attribution, style/layout cost and presentation delay hidden by the Long Tasks API's flat 50ms bucket.

In this guide
Table of Contents
Table of contents
A p75 Interaction to Next Paint (INP) score of 340ms with a Long Tasks API report showing nothing over 60ms is not a contradiction — it is a measurement gap. The Long Tasks API flags any main-thread block exceeding 50ms, but it treats the entire task as an opaque scripting blob. It cannot tell you whether the delay came from a third-party analytics script, a synchronous layout recalculation triggered by a CSS-in-JS library, or presentation delay waiting on the compositor. When you’re chasing INP regressions in a production SPA, that opacity is the bottleneck. The Long Animation Frames API (LoAF) exists specifically to close this attribution gap by decomposing a slow frame into its constituent phases: script execution, style/layout work, and render delay.
This article covers the architecture of LoAF entries, how to wire a PerformanceObserver pipeline that correlates them with real user interactions, and how to enforce frame-budget gates in CI before a regression reaches production RUM dashboards.
#Why the Long Tasks API Under-Reports INP Cost
INP measures the latency between a user interaction (click, keypress, tap) and the next paint that visually reflects the result. That latency spans four phases: input delay (main thread busy when the event fires), processing time (event handler execution), presentation delay (style recalculation, layout, paint, compositing, and the wait for the next vsync). The Long Tasks API only observes the second phase reliably. Presentation delay — frequently the largest contributor on layout-heavy dashboards — is invisible to it entirely.
The Long Animation Frames API specification addresses this by emitting a single PerformanceLongAnimationFrameTiming entry per slow frame, with a nested scripts array attributing duration to individual invokers (event handlers, promise resolutions, requestAnimationFrame callbacks) and explicit styleAndLayoutStart / renderStart timestamps. This turns a single flat 50ms number into a phase-resolved trace you can act on.
#Architectural Breakdown of a LoAF Entry
Each frame the browser renders passes through a defined pipeline: input handling, JavaScript execution (including microtasks and rAF callbacks), style recalculation, layout, paint, and compositing, followed by presentation to the screen. A LoAF entry is only generated when total frame duration exceeds the 50ms threshold, mirroring the Long Tasks API cutoff, but unlike Long Tasks it captures the full pipeline rather than just the scripting segment.
Rendering diagram...
Run the trace five times minimum per route and take the median rather than a single pass; frame timing on CI runners is noisy due to shared CPU contention, and a single-run gate produces flaky failures that erode trust in the check.
#Failure Modes and Edge Cases
The Long Animation Frames API has real limitations that will bite you in production if unaccounted for.
Cross-origin script attribution collapses. If the dominant script in a slow frame originates from a third-party origin without the Timing-Allow-Origin header, sourceURL and sourceFunctionName return empty strings. You’ll see the frame but not the culprit — a common scenario with ad tech, chat widgets, and analytics SDKs.

Buffer eviction under high-frequency interaction. The performance entry buffer has a bounded size (typically 200 entries pre-observer-registration). On interaction-heavy SPAs — infinite-scroll feeds, drag-and-drop builders — early frames get evicted before your observer flushes, silently truncating attribution data. Register the observer as early as possible in the document head, before hydration begins.
Browser support asymmetry. LoAF is Chromium-only as of current shipping versions. Firefox and Safari fall back to the Long Tasks API or nothing. Any INP diagnostics dashboard built on LoAF needs a feature-detection fallback path, otherwise your Safari traffic silently disappears from attribution reports rather than reporting degraded data.
rAF callback misattribution. Animation-driven UI libraries schedule work inside requestAnimationFrame, which LoAF attributes to the frame it executes in, not the frame that scheduled it. If your interaction handler defers heavy work via rAF to “avoid blocking,” the LoAF trace will still show it as the dominant script — deferral doesn’t remove the cost, it just moves the attribution window.
#Diagnostic Comparison Table
| API | Capture Scope | Threshold | Attribution Granularity | Best Use Case |
|---|---|---|---|---|
| Long Tasks API | Script execution only | 50ms | None (opaque task) | Coarse main-thread blocking alerts |
| Long Animation Frames API | Full pipeline: script, style, layout, render | 50ms | Per-script invoker, source, function | Root-causing INP regressions |
| Event Timing API | Interaction lifecycle | None (all interactions) | Input delay, processing, presentation delay totals | Computing INP score itself |
| Layout Instability API | Unexpected layout shifts | None | Affected DOM nodes | CLS diagnostics, not INP |
#Scaling and Security Trade-offs
Deploying LoAF-based attribution at fleet scale introduces cost and privacy considerations that need explicit sign-off from your platform and security teams before rollout.
- RUM ingestion volume — on high-traffic routes, batching every LoAF entry into your analytics pipeline can multiply event volume 3–5x versus Web Vitals alone; sample at 10–20% for high-cardinality routes and retain 100% only for checkout/critical-path flows.
- Source attribution as a data leak vector —
sourceFunctionNameand stack-adjacent fields can expose internal code structure or third-party vendor names in client-side network requests; strip or hash these fields before they leave the browser if your CSP or data governance policy restricts vendor disclosure. - Sampling bias on low-end devices — devices already struggling with main-thread contention generate disproportionately more LoAF entries, skewing your p75 upward if your sampling isn’t device-class stratified; segment aggregation by device memory/CPU tier rather than a flat global percentile.
- CI trace noise vs production fidelity — synthetic Puppeteer traces on shared CI runners rarely match real device thermal and CPU throttling behaviour, so a budget that passes in CI can still regress in the field; treat CI gating as a regression tripwire, not a substitute for RUM validation post-deploy.
Treat LoAF as the attribution layer that sits underneath your INP score rather than a replacement metric. The score tells stakeholders whether the experience is acceptable; the LoAF trace tells your engineering team exactly which invoker, source file, and pipeline phase to fix. Wiring both into the same dashboard, with CI gating catching regressions before they reach field measurement, closes the loop between synthetic testing and real-user telemetry that most performance monitoring stacks currently leave disconnected.
Evidence trail
Sources and verification
Primary documentation and external technical references used in this article.
Comments
Add a thoughtful note on Diagnosing INP Regressions via the LoAF API. Comments are checked for spam and held for moderation before appearing.
Related articles
Software Architecture
A Bounded Recovery Path for API-Driven Software Architecture Changes
How to design, validate and recover one bounded API architecture change with explicit evidence, bounded failure containment and a fixed rollback path.
Software Architecture
Building a Recoverable API Workflow for Software Architecture Reliability
A bounded, evidence-led approach to introducing and safely recovering a single API-mediated architectural change, using a routing boundary as the containment mechanism.
Software Architecture
Building a Failure-Aware API Workflow for Software Architecture
A bounded, failure-aware pattern for implementing a software architecture workflow on an API, with explicit validation stages, failure containment and a defined rollback ladder.
Software Architecture
Engineering Software Architecture for Predictable API Operations
How to design, canary-deploy, evidence-check and safely roll back a bounded API architecture change without treating any single layer as trustworthy on its own.
Learn More About KBY
About KBY
Learn about our mission, editorial standards, and commitment to trusted engineering knowledge.
Why Trust KBY
Explore the processes and policies that ensure our publications are accurate, useful, and responsible.
Newsletter
Get our latest editorial publications, research and practical insights sent directly to your inbox.
Was this useful?
Engineering insights, direct to you.
Receive the latest Systems Engineering tutorials, production guides, Engineering Labs and operational best practices.