Skip to content

Canvas-Driven Topographical Node Mapping for High-Density Networks #2

Description

@JamesEjembi

Problem Statement

Painting thousands of active verification nodes and their consensus channels dynamically using standard HTML elements causes massive browser DOM slowdowns. The current implementation renders each node as a React component wrapped in a <div> with inline styles for positioning; at 5,000+ nodes the DOM tree exceeds 15,000 elements (nodes + edges + labels), triggering layout thrashing and frame drops below 15 FPS during pan/zoom interactions.

Technical Bounds & Invariants

  • Target node count: 10,000 concurrent validators rendered at once
  • Minimum acceptable frame rate: 30 FPS during pan/zoom
  • Maximum memory budget for topology: 200 MB (browser tab limit)
  • Layout algorithm: force-directed graph with physics simulation at 60 updates/sec
  • Edge lines must show directional consensus flow (arrows) and latency color coding

Codebase Navigation Guide

  • Primary target: /src/components/network/NodeTopologyMap.tsx
  • Current (slow) SVG-based rendering: /src/components/network/NetworkGraph.tsx
  • Node data input: /src/hooks/useNodeTopology.ts — returns { nodes: Node[], edges: Edge[] }
  • Layout engine: /src/lib/forceLayout.ts — d3-force simulation

Step-by-Step Resolution Blueprint

  1. Replace the SVG/DOM rendering path with an HTML5 Canvas overlay using requestAnimationFrame for the render loop; implement a TopologyCanvas class that maintains a layer separation: (a) background grid layer, (b) edge layer, (c) node layer, (d) selection highlight layer
  2. Implement a spatial hash grid (cell size = 100px) to accelerate hit-testing on click/hover: on mousemove, check only the 3x3 cell neighborhood around the cursor position against the spatial hash; this reduces click detection from O(n) to O(1) for 10,000 nodes
  3. Port the d3-force simulation to run inside a Web Worker (/src/workers/forceLayout.worker.ts) using OffscreenCanvas for non-blocking physics ticks; transfer node/edge positions back to the main thread via postMessage at 30 FPS (every 2nd animation frame)
  4. For edge rendering, use a Path2D cache: recompute bezier curves only when topology changes (node add/remove), not every frame; store cached paths in a Map<edgeId, Path2D> and draw with ctx.stroke(cachedPath)
  5. Implement a dynamic level-of-detail system: nodes farther than 50% from viewport center render as 2px circles (no label); within 25% they render with full labels, status rings, and connection ports; use ctx.measureText only for visible-range nodes
  6. Add a WebGL fallback path using regl or pixi.js when navigator.gpu is available: encode node positions into a float32 vertex buffer and render as instanced point sprites for >5,000 nodes
  7. Write a performance regression test in Playwright that captures requestAnimationFrame timestamps during a 30s simulated topology with 10,000 nodes and asserts p95 frame time < 33ms (30 FPS)

Metadata

Metadata

Assignees

Labels

Complexity: HardcoreExtremely difficult, high-complexity engineering taskGrantFox OSSIssue tracked in GrantFox OSSLayer: UI-CoreCore UI layer architectural concernMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignType: Web3-IntegrationWeb3 wallet and blockchain integration issue

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions