-
Notifications
You must be signed in to change notification settings - Fork 77
Description
Problem
In SPAs with route-based rendering, navigating away from a page fully unmounts its components. When <Spline> unmounts, it calls app.dispose() and React removes the canvas from the DOM. On every return visit, a new canvas is created, a new WebGL context is initialized, and the scene reloads — meaning scenes on frequently visited routes always show a loading spinner, burning extra load time and WebGL context budget on every navigation.
We also observed canvas entries accumulating in Safari Web Inspector's Graphics tab across dispose/unmount cycles rather than being immediately released. There's no spec-level API to eagerly destroy a WebGL context, so the browser holds onto it until GC runs. This was also surfaced in #205 where users hit WebGL context errors after navigating back to a Spline page.
Proposed solution
Two changes working together:
1. applicationRef prop on <Spline>
Accept a React.MutableRefObject<Application | null> that the component populates on load and reads on remount. When a live Application is already in the ref, skip creating a new one and re-attach it to the newly mounted canvas. When applicationRef is provided, skip dispose() on unmount.
const splineApp = useRef<Application | null>(null);
<Spline scene={SCENE_URL} applicationRef={splineApp} />
2. Runtime-level canvas re-attachment in @splinetool/runtime
Since a WebGL context is permanently tied to the canvas it was created on, re-attaching an existing Application to a new canvas requires runtime support. The preferred approach would be a reattach(canvas) method on Application. If that's too invasive, an alternative is exposing the existing canvas reference so the React wrapper can manually move it into the new container on remount, avoiding the need for a new context entirely.
Without one of these, applicationRef alone can't avoid re-initializing the scene on remount — the canvas React creates on remount is a fresh element with no context.
Together these allow the Application and its loaded scene to survive route navigation entirely, with <Spline> handling all the lifecycle management internally.