성능 점검과 디버깅
GPU renderer를 쓴다고 자동으로 빠른 에디터가 되는 것은 아닙니다. 느린 hit test, 과한 buffer rebuild, 불필요한 draw call, 잘못된 texture upload는 여전히 문제를 만듭니다.
frame metrics를 수집하는 코드
renderer가 draw call과 upload 크기를 직접 기록하면 성능 병목을 찾기 쉽습니다.
function createFrameStats() {
return {
frameMs: 0,
drawCalls: 0,
bufferUploadBytes: 0,
textureUploads: 0,
hitTestMs: 0
};
}
function renderWithStats(renderer, snapshot) {
const stats = createFrameStats();
const start = performance.now();
renderer.render(snapshot, {
onDrawCall() {
stats.drawCalls += 1;
},
onBufferUpload(bytes) {
stats.bufferUploadBytes += bytes;
},
onTextureUpload() {
stats.textureUploads += 1;
}
});
stats.frameMs = performance.now() - start;
return stats;
}
hit test도 별도로 측정합니다.
function measuredHitTest(snapshot, worldPoint, stats) {
const start = performance.now();
const hit = hitTest(snapshot.drawList, worldPoint);
stats.hitTestMs = performance.now() - start;
return hit;
}
renderer backend는 같은 shape의 stats를 반환하게 둡니다.
interface RendererStats {
frameMs: number;
drawCalls: number;
bufferUploadBytes: number;
textureUploads: number;
visibleNodes: number;
culledNodes: number;
}
function renderStatusBar(root, stats, snapshot) {
root.textContent = [
`tool=${snapshot.tool}`,
`selected=${snapshot.selection.ids.length}`,
`drawCalls=${stats.drawCalls}`,
`upload=${Math.round(stats.bufferUploadBytes / 1024)}KB`,
`frame=${stats.frameMs.toFixed(1)}ms`
].join(" ");
}
먼저 측정한다
성능 개선은 느낌이 아니라 측정에서 시작합니다.
frame time
input latency
draw call count
buffer upload size
texture upload count
hit test cost
FPS만 보는 것은 부족합니다. 에디터에서는 pointer drag의 반응성이 더 중요할 수 있습니다.
renderer debug overlay를 둔다
개발 중에는 화면에 renderer 상태를 표시하는 overlay가 도움이 됩니다.
nodes: 1200
draw calls: 8
uploaded: 240KB
hover hit test: 0.3ms
이 정보는 제품 UI가 아니라 개발 도구입니다.
좌표 디버깅을 시각화한다
에디터 버그 중 많은 부분은 좌표계 문제입니다. world axis, selection bounds, local axes, hit test point를 overlay로 그리면 빠르게 찾을 수 있습니다.
screen point
world point
node local point
matrix readout
오늘의 핵심
성능과 디버깅은 나중에 붙이는 장식이 아닙니다. GPU editor를 유지보수하기 위한 도구입니다.
measure
visualize
isolate
fix
verify
이 루프가 있어야 capstone이 커져도 망가지지 않습니다.