🐧 Linux TippsDebian 11 Long Term Support reaches end-of-life(31.08.2026 um 02:00 Uhr)
🐧 Linux TippsUpdated Debian 13: 13.7 released(12.09.2026 um 02:00 Uhr)
🕵️ SicherheitslückenUSN-8741-1: Flatpak vulnerabilities(10.09.2026 um 10:44 Uhr)
🕵️ SicherheitslückenUSN-8742-1: Netty vulnerability(10.09.2026 um 11:01 Uhr)
🕵️ SicherheitslückenUSN-8737-2: GNU C Library vulnerabilities(10.09.2026 um 13:25 Uhr)
🕵️ SicherheitslückenUSN-8743-1: PHP vulnerabilities(10.09.2026 um 13:48 Uhr)
🕵️ SicherheitslückenUSN-8744-1: Python vulnerabilities(10.09.2026 um 15:53 Uhr)
🐧 Linux TippsUSN-8748-1: Linux kernel (NVIDIA) vulnerabilities(10.09.2026 um 17:32 Uhr)
🕵️ SicherheitslückenUSN-8745-1: KissFFT vulnerabilities(10.09.2026 um 17:36 Uhr)
🕵️ SicherheitslückenUSN-8746-1: libEBML vulnerability(10.09.2026 um 17:48 Uhr)
🐧 Linux TippsDebian 11 Long Term Support reaches end-of-life(31.08.2026 um 02:00 Uhr)
🐧 Linux TippsUpdated Debian 13: 13.7 released(12.09.2026 um 02:00 Uhr)
🕵️ SicherheitslückenUSN-8741-1: Flatpak vulnerabilities(10.09.2026 um 10:44 Uhr)
🕵️ SicherheitslückenUSN-8742-1: Netty vulnerability(10.09.2026 um 11:01 Uhr)
🕵️ SicherheitslückenUSN-8737-2: GNU C Library vulnerabilities(10.09.2026 um 13:25 Uhr)
🕵️ SicherheitslückenUSN-8743-1: PHP vulnerabilities(10.09.2026 um 13:48 Uhr)
🕵️ SicherheitslückenUSN-8744-1: Python vulnerabilities(10.09.2026 um 15:53 Uhr)
🐧 Linux TippsUSN-8748-1: Linux kernel (NVIDIA) vulnerabilities(10.09.2026 um 17:32 Uhr)
🕵️ SicherheitslückenUSN-8745-1: KissFFT vulnerabilities(10.09.2026 um 17:36 Uhr)
🕵️ SicherheitslückenUSN-8746-1: libEBML vulnerability(10.09.2026 um 17:48 Uhr)

🔧 Programmierung 🕛 vor 29 Tagen 3 Min Lesezeit
0

Your Three.js scene is leaking, and removing the mesh didn't help

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

The symptom is unmistakable once you've seen it: navigate between two views a dozen times and the tab climbs past a gigabyte, or the frame rate degrades and never recovers.




CODE
scene.remove(mesh)
mesh = null






Both lines run. Memory doesn't come back.






What remove does and doesn't do



scene.remove() detaches the object from the scene graph. That's all it does. JavaScript will happily collect the Mesh object itself.



But a Mesh is a thin wrapper. The actual data — vertex buffers, index buffers, texture uploads, compiled shader programs — lives in WebGL, on the GPU, allocated through the rendering context. The garbage collector has no visibility into that at all. Those resources are freed only when you explicitly ask.






What actually needs disposing



Three things, and each one is separate:




CODE
function disposeMesh(mesh) {
mesh.geometry.dispose()

const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]
for (const material of materials) {
for (const key of Object.keys(material)) {
const value = material[key]
if (value && value.isTexture) value.dispose()
}
material.dispose()
}
}






The texture loop matters more than it looks. A single MeshStandardMaterial can hold map, normalMap, roughnessMap, metalnessMap, aoMap, emissiveMap, displacementMap — seven separate uploads, none of which material.dispose() touches.






Doing it for a whole subtree






CODE
function disposeHierarchy(root) {
root.traverse((obj) => {
if (obj.isMesh || obj.isPoints || obj.isLine) disposeMesh(obj)
})
root.parent?.remove(root)
}






traverse visits the node and all descendants, so this handles a loaded glTF scene in one call.






The things that are easy to forget



Render targets. WebGLRenderTarget holds a framebuffer and at least one texture. Post-processing chains often hold several.




CODE
renderTarget.dispose()
composer.dispose()






Controls and listeners. OrbitControls attaches to the DOM element. Not disposing it keeps the whole scene alive through the listener closure — a plain JavaScript leak on top of the GPU one.




CODE
controls.dispose()






The renderer itself, when you're tearing down for good:




CODE
renderer.dispose()
renderer.forceContextLoss()






A browser will only give a page a limited number of WebGL contexts — commonly around 16. Create-and-abandon in a single-page app and you'll eventually get a blank canvas with Too many active WebGL contexts in the console, which is the same bug wearing a different hat.






Measure it, don't guess



The renderer exposes exactly what you need:




CODE
console.log(renderer.info.memory)    // { geometries: 42, textures: 17 }






Log this on every route change. In a healthy app the numbers return to baseline. If they only ever climb, you have your answer — and unlike a heap snapshot, this points directly at which resource type is leaking.






The framework wrapper



If you're on React Three Fiber, R3F disposes automatically when a component unmounts, which removes most of this problem. The exception is anything you constructed outside the render tree — a new THREE.TextureLoader().load(...) stored in a ref, a manually created render target — and those are exactly the cases where the automatic behaviour lulls you into not checking.



renderer.info.memory still tells the truth.






The takeaway




remove is about the scene graph. dispose is about the GPU. They are unrelated operations, and only one of them frees memory.







These posts come out of material I build for my Udemy courses — 25 of them now, mostly drill-based, across Go, Python, TypeScript, testing and Three.js. If this was useful, the full list is at udemy-c1f90.web.app. The links on that page carry a coupon I refresh each month, which usually lands around half the list price.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Debian 11 Long Term Support reaches end-of-life
1 Quelle
Updated Debian 13: 13.7 released
1 Quelle
USN-8741-1: Flatpak vulnerabilities