[Editor] Preload quick-access hold GLBs and improve loading UX
Problem
When a user drags a hold from the sidebar onto the 3D canvas, the GLB file is fetched on demand. This causes the entire canvas to flash white while Three.js/React Three Fiber suspends to load the model.
Currently, holds in the session's quick access panel are known ahead of time (they come from holds_collection_instances in the wall session response), but their GLB files are only loaded when the user actually drags one.
Proposed solution
1. Preload GLBs for all quick-access holds on session load
When the editor loads a wall session, iterate over the holds already in the quick access collection and call useGLTF.preload(glbUrl) for each one. This way, by the time the user drags a hold, the model is already cached in memory.
Relevant code:
EditorApp.tsx — already preloads some models but only from holds_collection_instances GLB URLs; this could be triggered earlier / more reliably
SidebarHoldsSection.tsx — calls useGLTF.preload() only when a new hold is added via the modal, not for holds already present
2. Preload newly added holds immediately
When a hold is added to the collection via AddHoldModal, its GLB should be preloaded right away (this partially works today but should be verified).
3. Add loading feedback in the sidebar
While GLB files are preloading, hold cards in the quick access panel should show some kind of loading state so the user knows the hold isn't ready to drag yet. The exact UX is up to the contributor (spinner, skeleton, faded state, etc.).
4. Prevent canvas white flash
Even with preloading, there should be a fallback so the canvas never goes fully white. Options are:
- Wrapping the drag preview
<Suspense> with a proper fallback (e.g. a simple placeholder mesh)
- Disabling drag for holds whose GLB hasn't finished loading yet
- Your solution :)
Checklist
Files to look at
| File |
Role |
features/editor/EditorApp.tsx |
Session load, existing preload logic |
features/editor/components/SidebarHoldsSection.tsx |
Hold cards, drag start |
features/editor/components/MainCanvas.tsx |
<Suspense> boundary, DragPreview |
features/editor/components/AddHoldModal.tsx |
Adding new holds to collection |
features/editor/components/ModelViewer.tsx |
useGLTF usage, onLoadComplete callback |
Labels
editor, performance, UX
Any questions ?
https://discord.gg/BdyfNU9TpR
[Editor] Preload quick-access hold GLBs and improve loading UX
Problem
When a user drags a hold from the sidebar onto the 3D canvas, the GLB file is fetched on demand. This causes the entire canvas to flash white while Three.js/React Three Fiber suspends to load the model.
Currently, holds in the session's quick access panel are known ahead of time (they come from
holds_collection_instancesin the wall session response), but their GLB files are only loaded when the user actually drags one.Proposed solution
1. Preload GLBs for all quick-access holds on session load
When the editor loads a wall session, iterate over the holds already in the quick access collection and call
useGLTF.preload(glbUrl)for each one. This way, by the time the user drags a hold, the model is already cached in memory.Relevant code:
EditorApp.tsx— already preloads some models but only fromholds_collection_instancesGLB URLs; this could be triggered earlier / more reliablySidebarHoldsSection.tsx— callsuseGLTF.preload()only when a new hold is added via the modal, not for holds already present2. Preload newly added holds immediately
When a hold is added to the collection via
AddHoldModal, its GLB should be preloaded right away (this partially works today but should be verified).3. Add loading feedback in the sidebar
While GLB files are preloading, hold cards in the quick access panel should show some kind of loading state so the user knows the hold isn't ready to drag yet. The exact UX is up to the contributor (spinner, skeleton, faded state, etc.).
4. Prevent canvas white flash
Even with preloading, there should be a fallback so the canvas never goes fully white. Options are:
<Suspense>with a proper fallback (e.g. a simple placeholder mesh)Checklist
Files to look at
features/editor/EditorApp.tsxfeatures/editor/components/SidebarHoldsSection.tsxfeatures/editor/components/MainCanvas.tsx<Suspense>boundary,DragPreviewfeatures/editor/components/AddHoldModal.tsxfeatures/editor/components/ModelViewer.tsxuseGLTFusage,onLoadCompletecallbackLabels
editor,performance,UXAny questions ?
https://discord.gg/BdyfNU9TpR