From 8c5b452f738806c2b5b0b085d26261506036b2b2 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Tue, 10 Mar 2026 00:47:27 +0100 Subject: [PATCH] Batch 8000 SVG circles into single path element in DottedMap Instead of rendering 8000 individual elements (each a React node to reconcile), batch all map dots into a single string. Reduces DOM nodes from ~8000 to 1 for the base map layer. Co-Authored-By: Claude Opus 4.6 --- components/dashboard/DottedMap.tsx | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/components/dashboard/DottedMap.tsx b/components/dashboard/DottedMap.tsx index 94197b3..f2c9bea 100644 --- a/components/dashboard/DottedMap.tsx +++ b/components/dashboard/DottedMap.tsx @@ -77,6 +77,21 @@ export default function DottedMap({ data, className }: DottedMapProps) { return { xStep: step || 1, yToRowIndex: rowMap } }, [points]) + // Batch all 8000 base dots into a single instead of 8000 elements + const dotsPath = useMemo(() => { + const r = dotRadius + const d = r * 2 + const parts: string[] = [] + for (const point of points) { + const rowIndex = yToRowIndex.get(point.y) ?? 0 + const offsetX = rowIndex % 2 === 1 ? xStep / 2 : 0 + const cx = point.x + offsetX + const cy = point.y + parts.push(`M${cx - r},${cy}a${r},${r} 0 1,0 ${d},0a${r},${r} 0 1,0 ${-d},0`) + } + return parts.join('') + }, [points, dotRadius, xStep, yToRowIndex]) + return (
- {points.map((point, index) => { - const rowIndex = yToRowIndex.get(point.y) ?? 0 - const offsetX = rowIndex % 2 === 1 ? xStep / 2 : 0 - return ( - - ) - })} + {processedMarkers.map((marker, index) => { const rowIndex = yToRowIndex.get(marker.y) ?? 0 const offsetX = rowIndex % 2 === 1 ? xStep / 2 : 0