2026 02 24_performance_tuning_plan - mark-ik/graphshell GitHub Wiki
Status: Implementation-Ready
Supersedes: 2026-02-11_performance_optimization_plan.md
Context: Post-Registry migration cleanup and scaling.
Relates to: ../graph/multi_view_pane_spec.md (per-graph-pane culling/LOD semantics and graph-view isolation)
Target performance envelopes on reference hardware:
- 500 nodes @ 60 FPS
- 1000 nodes @ 30+ FPS
-
CanvasRegistry: runtime toggles/policies (viewport_culling_enabled,label_culling_enabled, edge LOD mode). -
DiagnosticRegistry: frame-time/entity metrics with bounded sampling. -
MetadataFrame: per-graph-pane previous-frame zoom/pan oracle used for LOD and viewport decisions. -
render/spatial_index.rs: viewport candidate lookup using spatial index (avoid full O(N) scans). - Multi-pane rule: culling and LOD decisions are computed per graph pane, not globally.
- Compute visible world rect from previous-frame camera metadata.
- Query spatial index for candidate visible nodes.
- Submit only visible nodes to
egui_graphs.
- Validate behavior when edge endpoints are culled.
- If renderer requires both endpoints present, add explicit edge filtering/ghost endpoint policy.
- Add/confirm
viewport_culling_enabledinCanvasRegistry.
- Zoom
< 0.5: hide labels. - Zoom
0.5..=1.5: domain-only label. - Zoom
> 1.5: full title.
- Rank visible nodes by importance (selection + graph importance).
- Greedy rect packing: skip intersecting lower-priority labels.
- Zoom
< 0.3: hide non-critical edges or all edges by policy. - Zoom
< 0.8: reduced alpha/width, no arrowheads. - Zoom
>= 0.8: full edge styling.
- Add/confirm
label_culling_enabledand edge LOD policy inCanvasRegistry.
- Cap animated badges per frame (initial cap:
20). - Disable animation for nodes beyond view-center distance threshold.
- Fallback to static badge rendering when budget is exhausted.
- If average displacement remains below epsilon for N frames, pause simulation.
- Resume on structural/interaction intent.
- Bound physics update work per frame (initial budget target: ~5ms).
- Carry remaining simulation work to subsequent frames.
- Favor frame responsiveness over instant convergence.
- Keep Barnes-Hut as deferred path for sustained >1000 node regimes.
To avoid observer-effect distortion:
- Keep diagnostic aggregation/render sampling bounded (10 Hz target for diagnostic updates).
- Keep main UI/render loop unconstrained by diagnostic refresh cadence.
- 500-node benchmark at zoomed-out view meets 60 FPS target band.
- 1000-node benchmark meets 30+ FPS target band.
- Viewport culling produces expected visible-set reduction and frame-time drop.
- Label and edge LOD transitions occur at configured zoom thresholds.
- Physics budget cap prevents long-frame spikes during active simulation.
- Diagnostics enabled vs disabled does not materially skew benchmark readings.