Skip to content

Improve 3d model loading to avoid laggy browser#742

Open
victorjzq wants to merge 1 commit intotscircuit:mainfrom
victorjzq:fix/issue-93
Open

Improve 3d model loading to avoid laggy browser#742
victorjzq wants to merge 1 commit intotscircuit:mainfrom
victorjzq:fix/issue-93

Conversation

@victorjzq
Copy link
Copy Markdown

/claim #93

The browser was getting laggy because every component render triggered fresh network fetches and full model parses for the same URLs — no deduplication at all. I added a global window.TSCIRCUIT_3D_MODEL_CACHE that stores both the in-flight promise and the resolved result, so concurrent requests for the same model share one fetch and subsequent renders just clone the cached object. Using .clone() was the key thing to get right here — Three.js objects are stateful, so sharing a single instance across the scene would cause transform conflicts.

Fixes #93

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
3d-viewer Ready Ready Preview, Comment Mar 19, 2026 1:09pm

Request Review

Comment on lines +69 to +74
const promise = loadModel(cleanUrl).then((result) => {
cache.set(cleanUrl, { ...cache.get(cleanUrl)!, result })
return result
})
cache.set(cleanUrl, { promise, result: null })
return promise
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first caller receives the original un-cloned THREE.Object3D while subsequent callers receive clones. This defeats the purpose of cloning mentioned in the description ("Three.js objects are stateful, so sharing a single instance across the scene would cause transform conflicts"). The first caller can mutate the cached object, corrupting it for all future callers.

Fix by returning a clone:

const promise = loadModel(cleanUrl).then((result) => {
  cache.set(cleanUrl, { ...cache.get(cleanUrl)!, result })
  return result?.clone() ?? null
})
Suggested change
const promise = loadModel(cleanUrl).then((result) => {
cache.set(cleanUrl, { ...cache.get(cleanUrl)!, result })
return result
})
cache.set(cleanUrl, { promise, result: null })
return promise
const promise = loadModel(cleanUrl).then((result) => {
cache.set(cleanUrl, { ...cache.get(cleanUrl)!, result })
return result?.clone() ?? null
})
cache.set(cleanUrl, { promise, result: null })
return promise

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve 3d model loading to avoid laggy browser

1 participant