perf: cache polygon conversions to fix performance regression
CRITICAL PERFORMANCE FIX: Converting SVG paths to Polygons on every mouse move was causing severe lag. Cache the polygons per region ID. Problem: - pathToPolygon() samples 50 points using getTotalLength() + getPointAtLength() - This was being called for EVERY region on EVERY mouse move - For world map with ~200 regions, this was 200 expensive conversions per frame - Completely unusable performance Solution: - Cache Polygon objects in a Map<regionId, Polygon> - Only compute polygon once per region, reuse on subsequent detections - Clear cache when map data changes (continent/map selection) Performance improvement: - Before: ~200 polygon conversions per mouse move - After: ~200 polygon conversions total (one-time cost), 0 per mouse move - Detection now runs at full frame rate 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
743adae92d
commit
348ce8f314
|
|
@ -15,7 +15,7 @@
|
|||
* bounding boxes. This prevents false positives from irregularly shaped regions.
|
||||
*/
|
||||
|
||||
import { useState, useCallback, type RefObject } from 'react'
|
||||
import { useState, useCallback, useRef, useEffect, type RefObject } from 'react'
|
||||
import type { MapData } from '../types'
|
||||
import { Polygon, Box, point as Point } from '@flatten-js/core'
|
||||
|
||||
|
|
@ -120,6 +120,14 @@ export function useRegionDetection(options: UseRegionDetectionOptions): UseRegio
|
|||
|
||||
const [hoveredRegion, setHoveredRegion] = useState<string | null>(null)
|
||||
|
||||
// Cache polygons to avoid expensive recomputation on every mouse move
|
||||
const polygonCache = useRef<Map<string, Polygon>>(new Map())
|
||||
|
||||
// Clear cache when map data changes
|
||||
useEffect(() => {
|
||||
polygonCache.current.clear()
|
||||
}, [mapData])
|
||||
|
||||
/**
|
||||
* Detect regions at the given cursor position.
|
||||
*
|
||||
|
|
@ -218,8 +226,12 @@ export function useRegionDetection(options: UseRegionDetectionOptions): UseRegio
|
|||
|
||||
// For overlap detection, use flatten-js for precise geometric intersection
|
||||
try {
|
||||
// Convert region path to Polygon (in SVG coordinates)
|
||||
const regionPolygon = pathToPolygon(regionPath)
|
||||
// Get or create cached polygon for this region
|
||||
let regionPolygon = polygonCache.current.get(region.id)
|
||||
if (!regionPolygon) {
|
||||
regionPolygon = pathToPolygon(regionPath)
|
||||
polygonCache.current.set(region.id, regionPolygon)
|
||||
}
|
||||
|
||||
// Convert detection box to SVG coordinates
|
||||
const boxTopLeft = svgElement.createSVGPoint()
|
||||
|
|
|
|||
Loading…
Reference in New Issue