Skip to content

Improve: Performance optimizations — draw calls, VRAM, imports, DOM#95

Merged
arossti merged 6 commits intomainfrom
mhp/performance-improvements
Feb 15, 2026
Merged

Improve: Performance optimizations — draw calls, VRAM, imports, DOM#95
arossti merged 6 commits intomainfrom
mhp/performance-improvements

Conversation

@mhpavl
Copy link
Collaborator

@mhpavl mhpavl commented Feb 15, 2026

Summary

  • Fix GPU memory leaks by disposing geometries/materials on group clearing
  • Reduce draw calls ~200x for matrix scenes via InstancedMesh and merged BufferGeometry
  • Eliminate async overhead by converting 13 dynamic imports to static
  • Cache 206 DOM element references and debounce slider input events
  • Replace string-based vertex deduplication with spatial hashing

Changes

  • Fix 1: disposeGroup() utility replaces 17 bare while-loop group clears in rt-rendering.js
  • Fix 2: InstancedMesh for matrix nodes in rt-nodes.js, with InstancedMesh support added to rt-papercut.js and rt-viewmanager.js
  • Fix 3: Merged matrix geometries via buildMergedMatrix() helper in rt-matrix-planar.js and rt-matrix-radial.js (net -420 lines)
  • Fix 4: Cached DOM references (el.xxx lookups) and rAF-gated requestGeometryUpdate() for slider events
  • Fix 5: Static imports for rt-matrix-planar, rt-matrix-radial, and rt-polyhedra in render paths
  • Fix 6: SpatialVertexSet class with integer-quantized keys replaces toFixed(6) string serialization

Test plan

  • All 5 Platonic solids render correctly with faces, edges, and nodes
  • 10×10 cube matrix with packed nodes (stress test)
  • Radial matrices at multiple frequencies
  • Papercut intersections still detect nodes
  • State save/load still functions
  • No console errors or WebGL warnings
  • GPU memory stable during slider drag sessions

Created disposeGroup() utility that properly disposes geometry and
material GPU resources before removing children. Replaced all 17 bare
while-loop group-clearing patterns throughout rt-rendering.js.

Prevents VRAM exhaustion from orphaned BufferGeometry and Material
objects accumulating during slider adjustments and form updates.
Convert addMatrixNodes and addRadialMatrixNodes in rt-nodes.js to use
THREE.InstancedMesh instead of creating individual meshes per vertex.
For a 10x10 cube matrix (~400 nodes), this reduces draw calls from
400 to 1 per node group.

Primary polyhedra nodes (renderPolyhedron) kept as individual meshes
to preserve instance cloning and vertex selection compatibility.

Updated rt-papercut.js and rt-viewmanager.js to handle InstancedMesh
by iterating stored vertexPositions from userData.
Replace per-cell geometry creation with pre-allocated merged arrays.
Each matrix now creates ONE face mesh + ONE edge LineSegments instead
of N² separate objects. For a 10x10 cube matrix, this reduces draw
calls from ~200 to 2.

Added buildMergedMatrix() helper to both planar and radial modules.
Handles tetrahedron alternating orientations via flipZ flag (planar)
and up/down geometry split (radial). Radial octahedron ivmScaleOnly
mode retains per-cell approach due to per-cell rotation requirement.

Net reduction: -502 lines of duplicated per-cell geometry code.
Convert 13 dynamic import() calls to static imports:
- rt-rendering.js: 11 dynamic imports of rt-matrix-planar and rt-matrix-radial
- rt-nodes.js: 2 dynamic imports of rt-polyhedra
No circular dependencies — all conversions are safe.
Add SpatialVertexSet class using integer-quantized keys instead of
toFixed(6) string serialization. Eliminates string allocation churn
and parseFloat round-trips during node position deduplication.
- Cache all DOM elements with IDs at init time via querySelectorAll
- Replace 206 document.getElementById() calls with cached el.xxx lookups
- Add requestGeometryUpdate() with rAF gating for slider input events
- Checkbox/radio change events remain synchronous (fire once per click)
@github-actions
Copy link

🤖 Claude Code Review

No issues found.


ℹ️ About this review

This automated review checks for:

  • Debug statements (console.log)
  • Commented-out code
  • Code duplication
  • Large functions (>50 lines)
  • Unused variables

Human review required - these are suggestions only.
Diff size: 148222 bytes

@arossti arossti self-assigned this Feb 15, 2026
@arossti arossti merged commit d6f45c0 into main Feb 15, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants