Prompt
Use InteractionManager.runAfterInteractions to defer a heavy computation (simulated with a loop of 100M iterations) until after navigation transitions complete.
Solution
The failure mode this solves is structural: a JS-driven navigation transition and your mount-time heavy work compete for the same JS thread, so the transition stutters. InteractionManager.runAfterInteractions sequences instead of competing — defer the expensive work, keep the transition's frame budget intact, run the work immediately after.
Mechanically it's a handle registry, not magic: animations register an interaction handle (createInteractionHandle) and release it when done — the Animated API does this internally. While any handle is open, deferred callbacks queue; when the count hits zero, the queue flushes. That mechanism defines its blind spot, and naming it is the senior move: UI-thread animations — native-driver Animated and Reanimated worklets — never register JS-side handles, so runAfterInteractions can resolve while such a transition is still visibly running. For navigation specifically, React Navigation's transition-end events are the more precise deferral point.
Two production details in the code: task.cancel() in the effect cleanup stops the deferred work if the user backs out before it runs, and the ready placeholder means the screen paints something immediately — deferral plus skeleton, not a blank frame. And honestly: a 100M-iteration loop will still freeze the JS thread when it runs; InteractionManager schedules work, it doesn't parallelize it. Truly heavy compute belongs off-thread.
Red flag: claiming InteractionManager "detects when animations finish." It only sees explicitly registered handles.
Say it: "runAfterInteractions defers JS-thread work until registered interaction handles release — but native-driver and Reanimated animations are invisible to it, so for navigation I prefer transition-end events."