Skip to content

HideChildrenIfFronteggRoutes burns CPU with infinite requestAnimationFrame loop; login-box runs setInterval(50ms) when authenticated #1331

@AmarShaked

Description

@AmarShaked

Description

Frontegg's React SDK has two CPU-intensive polling loops that run continuously while the application is idle, causing significant CPU consumption even when the user is fully authenticated and not interacting with the page.


Issue 1: requestAnimationFrame polling loop in HideChildrenIfFronteggRoutes

The HideChildrenIfFronteggRoutes component runs a self-scheduling requestAnimationFrame loop that checks window.location.pathname every frame (~60fps) to detect route changes to Frontegg-hosted routes (e.g. /account/login).

Source: @frontegg/react bundle (observed at offset ~28271)

Trace evidence: In a Chrome performance trace over ~11 seconds of idle time, we recorded 1,191 RequestAnimationFrame events originating from this callback, making it the single largest CPU consumer in the application.

Why this is unnecessary: The component already has popstate and custom event listeners that handle URL changes. The rAF loop appears to be a fallback for pushState/replaceState calls (which don't fire popstate), but a more efficient approach would be to patch pushState/replaceState to dispatch events, rather than polling at 60fps indefinitely.

Issue 2: setInterval at 50ms in login-box bundle

The Frontegg login-box bundle installs a setInterval with a ~50ms interval that continues running even after the user is fully authenticated. Over an 11-second idle trace, this timer fired 208 times, consuming 1,136ms of scripting CPU.

Source: frontegg/login-box bundle


Impact

Metric Before fix After fix
Chrome idle CPU ~20% <1%
Brave idle CPU ~100% <1%
Scripting time (11s idle trace) 601ms 13ms

This affects all customers using the @frontegg/react SDK. Users on lower-powered devices or battery-constrained laptops are particularly impacted.


Steps to Reproduce

  1. Set up a React app with @frontegg/react using hostedLoginBox={false}
  2. Log in as any user
  3. Open Chrome DevTools → Performance tab → Record for 10–15 seconds while idle
  4. Observe continuous RequestAnimationFrame and TimerFire events originating from Frontegg bundles

Expected Behavior

When the user is authenticated and the application is idle, Frontegg should not consume any meaningful CPU. Route detection should use event-driven mechanisms rather than polling.


Our Workaround

We currently intercept requestAnimationFrame and suppress callbacks that self-reschedule 60+ times consecutively (threshold-based detection of infinite loops), and detect/clear short-interval timers after confirming they're polling loops. We also patch pushState/replaceState to dispatch popstate events so Frontegg's existing listener still detects route changes.

This works but is fragile and shouldn't be necessary.

Environment

  • @frontegg/react: 7.12.18
  • React 19
  • Chromium-based browsers (Chrome, Brave, Edge)

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions