Measured while implementing #5953 (PR #5975). Out of that card's scope — filing plainly for triage to grade.
What was measured
packages/plugin-map/src/ObjectMap.tsx:594 calls the config builder straight in the render body, unmemoized:
constmapConfig=getMapConfig(schema);
Every render therefore produces a new object identity. The marker transform names it in its dependency array (ObjectMap.tsx:737):
},[data,mapConfig,objectSchema]);
so that useMemo recomputes on every single render — it is a useMemo in spelling only. The recomputation walks all records through extractCoordinates and the display-name resolver. Downstream, filteredMarkers / clusteredData / markerBounds each depend on markers, so the invalidation cascades through the whole marker pipeline.
The sibling dataConfig immediately above it (ObjectMap.tsx:590) shows the shape the file already knows about, deliberately memoized on a deep-compare key:
constdataConfig=useMemo(()=>rawDataConfig,[JSON.stringify(rawDataConfig)]);
mapConfig got no equivalent.
Second-order cost inside getMapConfig itself
Because it is unmemoized, everything getMapConfig does happens per render, not per config change:
ObjectMapConfigSchema.safeParse(config) — a full zod parse on every render when a declared map block is present;warnOnLegacyFilterMapConfig, warnOnTopLevelStyleUrl, warnOnShadowedFlatMapKeys.
The warn helpers are documented as warning "once per distinct stash" and carry their own dedupe, so this is a cost question rather than a log-spam one — but it is being paid on a per-render cadence.
Why this is worth its own card rather than a rider
It is not a correctness bug on any path I exercised: the recompute is wasteful, not wrong, and #5953's own change (adding objectSchema to that dep array, which it genuinely needs — the object definition arrives from an async fetch after first paint) neither causes nor worsens it. The fix is a different shape from that card's — memoize mapConfig, presumably on the same deep-compare key idiom the neighbouring dataConfig already uses — and touching it there would have been unreviewable scope creep inside a display-name fix.
Unassigned; filed plainly for triage to grade.
Generated by Claude Code
Measured while implementing #5953 (PR #5975). Out of that card's scope — filing plainly for triage to grade.
What was measured
packages/plugin-map/src/ObjectMap.tsx:594calls the config builder straight in the render body, unmemoized:Every render therefore produces a new object identity. The marker transform names it in its dependency array (
ObjectMap.tsx:737):so that
useMemorecomputes on every single render — it is auseMemoin spelling only. The recomputation walks all records throughextractCoordinatesand the display-name resolver. Downstream,filteredMarkers/clusteredData/markerBoundseach depend onmarkers, so the invalidation cascades through the whole marker pipeline.The sibling
dataConfigimmediately above it (ObjectMap.tsx:590) shows the shape the file already knows about, deliberately memoized on a deep-compare key:mapConfiggot no equivalent.Second-order cost inside
getMapConfigitselfBecause it is unmemoized, everything
getMapConfigdoes happens per render, not per config change:ObjectMapConfigSchema.safeParse(config)— a full zod parse on every render when a declaredmapblock is present;warnOnLegacyFilterMapConfig,warnOnTopLevelStyleUrl,warnOnShadowedFlatMapKeys.The warn helpers are documented as warning "once per distinct stash" and carry their own dedupe, so this is a cost question rather than a log-spam one — but it is being paid on a per-render cadence.
Why this is worth its own card rather than a rider
It is not a correctness bug on any path I exercised: the recompute is wasteful, not wrong, and #5953's own change (adding
objectSchemato that dep array, which it genuinely needs — the object definition arrives from an async fetch after first paint) neither causes nor worsens it. The fix is a different shape from that card's — memoizemapConfig, presumably on the same deep-compare key idiom the neighbouringdataConfigalready uses — and touching it there would have been unreviewable scope creep inside a display-name fix.Unassigned; filed plainly for triage to grade.
Generated by Claude Code