dispose, cache, renderer.info로 성능 관리하기
Three.js는 JavaScript object를 지웠다고 GPU resource까지 자동으로 정리하지 않습니다. editor는 node 생성/삭제와 undo/redo가 많기 때문에 dispose 정책이 필요합니다.
resource owner를 정한다
geometry.dispose();
material.dispose();
texture.dispose();
renderer backend가 geometry/material/texture cache를 소유한다면, 삭제된 node와 더 이상 쓰이지 않는 resource를 backend가 정리해야 합니다.
renderer.info를 본다
console.table(renderer.info.render);
console.table(renderer.info.memory);
프레임마다 draw call이 늘거나 texture count가 계속 증가하면 cache나 dispose 정책을 의심해야 합니다.
Object3D를 안전하게 dispose한다
function disposeObject(object) {
object.traverse((child) => {
if (child.geometry) {
child.geometry.dispose();
}
const materials = Array.isArray(child.material)
? child.material
: child.material ? [child.material] : [];
for (const material of materials) {
for (const value of Object.values(material)) {
if (value && value.isTexture) value.dispose();
}
material.dispose();
}
});
}
function assertRendererMemory(renderer, limits) {
const { geometries, textures } = renderer.info.memory;
if (geometries > limits.geometries || textures > limits.textures) {
console.warn("renderer resource leak?", renderer.info.memory);
}
}
삭제와 undo/redo가 많은 editor에서는 dispose를 helper로 고정해두는 편이 좋습니다. 개발 중에는 renderer.info.memory를 limit과 비교해서 누수가 초기에 보이도록 만듭니다.
오늘의 핵심
Three.js editor의 성능 문제는 대개 lifecycle 문제입니다. 만든 resource를 누가 언제 버리는지 코드로 정해야 합니다.