Skip to content

[iOS/Android] idleHostTTL prop to defer host destruction after unmount #30

@KarthikMAM

Description

@KarthikMAM

Problem

In a conversation UI, sandbox cards scroll in and out of the viewport constantly. A user reads a long text response, scrolls past three weather cards, then scrolls back up to check the forecast again. Today, each of those cards is destroyed the moment it leaves the viewport and cold-started from scratch when it comes back.

On a Release build (iPhone 17 Pro simulator), that’s 89ms per card every time the user scrolls back. In a feed with several cards, this creates visible jank during scroll-back — the cards pop in one by one instead of appearing instantly.

The underlying issue: when React unmounts a SandboxReactNativeView, the shared ReactHost is destroyed immediately if no other surfaces reference it. There’s no grace period for the common case where the user is about to scroll right back.

Proposed solution

An idleHostTTL prop (milliseconds) that tells the runtime how long to keep a shared host alive after the last surface detaches:

<SandboxReactNativeView
  origin="weather"
  idleHostTTL={2000}
  componentName="WeatherCard"
  jsBundleSource="sandbox"
/>

With idleHostTTL={2000}, when the last weather card scrolls off-screen, the Hermes VM stays warm for 2 seconds. If the user scrolls back within that window, the card remounts in ~4ms (warm) instead of 89ms (cold). If they don’t scroll back, the VM is cleaned up after the TTL expires.

idleHostTTL={0} (default) preserves current behavior — eager destroy on unmount.

Use cases

Conversation feeds — Cards leave and re-enter the viewport during normal reading. A 2–5s TTL covers typical scroll-back patterns without holding memory indefinitely.

Tab switching — User switches away from a tab containing sandbox content and returns shortly after.

Carousels — Swiping through a horizontal card pager where adjacent cards are just off-screen.

Additional context

The prop is already defined in the codegen spec (as idleTTL) and accepted by the JS component. The native implementation needs to honor it during the host cleanup path on both platforms. Related: #28, #29.

Environment

Field Value
react-native-sandbox 0.6.0
React Native 0.80.1
Platform iOS, Android

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions