@vectorvesper/motion/reactReact Adapters · Deferral Gate

useSafeToMount

Mounting heavy visual subtrees (3D canvases, WebGL visualizers, interactive data charts) during initial hydration compounds main-thread jank and causes frame drops. useSafeToMount continuously monitors frame headroom, holding the component behind a lightweight placeholder until the main thread proves it has enough spare frame headroom to absorb initial compilation and layout costs without stutter.

The useSafeToMount hook returns true once the page demonstrates enough spare frame headroom to absorb an expensive mount. Use it to defer non-essential heavy subtrees (3D models, complex charts, video players) during page load.

It initializes to false during server rendering and hydration. Once the frame loop proves consistent spare headroom, it flips to true and stays true for the remainder of the component's lifecycle. The gate is intentionally one-way: a component that unmounted itself the moment it created load would oscillate endlessly.

For a full 3D viewport that combines visibility intersection with headroom gating, see useSceneGate. For dynamic quality adaptation on already-running scenes, consult AdaptiveQuality.

Main-Thread Hydration & Mount Staggering

Instant KPI Row+ Hydration Settles Chart Mounts Cleanly
Demo loads on scroll

Quick start

Mount lightweight placeholder poster in the initial render, swapping in the heavy interactive subtree once headroom is confirmed.

The hook starts false on server render and hydration, evaluating headroom over consecutive frames before resolving to true.

MountCost Thresholds & Hardware Floor Matrix

Predefined cost tiers determine minimum headroom, consecutive clean frames, and hardware core requirements.

Cost TierHeadroom (ms)Clean FramesMin CoresTypical Target Components
"light"1 ms1 frame2 coresSmall 2D canvas, animated SVG widgets, tooltips.
"normal"2 ms2 frames4 coresDefault. Interactive charts, carousel sliders, audio players.
"heavy"6 ms3 frames4 coresFull Three.js 3D viewports, particle systems, video engines.

API Reference

Syntax

Evaluates frame headroom and hardware concurrency before authorizing component initialization.

Parameters

Parameters.fieldTypeDefaultDescription
options.cost"light" | "normal" | "heavy""normal"Complexity tier of the component to mount. Configures required headroom and required clean frames.

Return Value

boolean

Returns false initially; flips to true once the main thread demonstrates adequate headroom.

SAFE_TO_MOUNT_COST Reference

SAFE_TO_MOUNT_COST Reference.fieldCostThresholdsDescription
light1ms headroom · 1 clean frame · min 2 coresLightweight canvas widgets and micro-interactions.
normal2ms headroom · 2 clean frames · min 4 coresDefault setting for standard dynamic components.
heavy6ms headroom · 3 clean frames · min 4 coresResource-heavy 3D scenes, WebGL shaders, and vendor bundles.

Lifecycle & Cleanup

useSafeToMount automatically manages its conductor subscription and cleans up upon resolution.

One-Way Latch LifecycleNever oscillates backward

Lifecycle & Invariant Guarantees

  • One-way latch guarantee: Once safe becomes true, it never flips back to false, preventing infinite mount/unmount thrash cycles.
  • Hydration safety: Always starts false on the server and initial client render, guaranteeing zero React hydration mismatches.
  • Hardware concurrency floor: Devices below the minimum required CPU core count gracefully stay false, permanently skipping heavy initialization.
  • Refresh-rate relative headroom: Headroom calculations scale relative to detected display refresh rate (e.g. 16.7ms vs 8.3ms), remaining fair on 120Hz displays.

Production Examples

Battle-tested production patterns ready to copy directly into your codebase.

Mount lightweight KPI summary statistics instantly while deferring expensive canvas chart initialization.

When NOT to use this

The component is computationally cheap to mount.
→ instead Render it directly. Adding a skeleton and delayed mount is worse UX than immediately mounting a cheap component.
The component is below the fold and not yet visible.
→ instead Use useSceneGate: it combines visibility intersection with useSafeToMount headroom verification.
You want to dynamically adjust quality in a scene already running.
→ instead Use AnimationBudget or AdaptiveQuality. useSafeToMount only answers the initial mount authorization once.
The component is required for fundamental correctness (checkout buttons, auth forms).
→ instead Render unconditionally. Performance gates must only defer decorative or analytical subtrees.

Rules & Gotchas

  • Always provide an identically sized placeholder: Use a skeleton or poster matching the target component dimensions to guarantee zero Cumulative Layout Shift (CLS) on swap.
  • The gate waits and never aborts on transient spikes: Hydration is busy by definition. The gate patiently buffers until the initial burst settles without needing remount keys.
  • Pass a static cost option string: Options are effect dependencies; passing dynamic objects that change every render will continuously reset the gate.
  • Headroom scales across refresh rates: 6ms headroom represents ~36% of a 60Hz frame (16.7ms) and ~72% of a 120Hz frame (8.3ms), remaining stricter on faster screens.

Related Motion Components