perf(web): release monitor resources on unmount

This commit is contained in:
lingniu
2026-07-16 00:59:57 +08:00
parent c00f50551a
commit e80e1dcea9
9 changed files with 194 additions and 37 deletions

View File

@@ -171,6 +171,11 @@ export function FleetMap({ vehicles, selectedVin, onSelect, monitorMap, onSelect
let cancelled = false;
let resizeTimer: number | undefined;
let resizeObserver: ResizeObserver | undefined;
let mapInstance: AMapMap | undefined;
let massInstance: AMapMassMarks | undefined;
let selectMassPoint: ((event: { data: AMapMassPoint }) => void) | undefined;
let notifyViewport: (() => void) | undefined;
let stopFollowing: (() => void) | undefined;
setState('loading');
loadAMap(['AMap.Scale', 'AMap.ToolBar']).then((AMap) => {
if (cancelled || !containerRef.current) return;
@@ -186,13 +191,15 @@ export function FleetMap({ vehicles, selectedVin, onSelect, monitorMap, onSelect
showLabel: true,
resizeEnable: true
});
mapInstance = map;
map.addControl(new AMap.Scale());
if (AMap.ToolBar) map.addControl(new AMap.ToolBar({ position: { right: '18px', bottom: '76px' } }));
const styles = [
...COLORS.map((color) => ({ url: dotDataUrl(color), anchor: new AMap.Pixel(9, 9), size: new AMap.Size(18, 18) }))
];
const mass = new AMap.MassMarks([], { opacity: 0.96, zIndex: 120, cursor: 'pointer', style: styles, zooms: [3, 20] });
mass.on('click', (event) => {
massInstance = mass;
selectMassPoint = (event: { data: AMapMassPoint }) => {
const cluster = clustersRef.current.get(event.data.id);
if (cluster) {
map.setZoomAndCenter?.(Math.min(20, (map.getZoom?.() ?? 5) + 2), wgs84ToGcj02(cluster.longitude, cluster.latitude));
@@ -204,12 +211,13 @@ export function FleetMap({ vehicles, selectedVin, onSelect, monitorMap, onSelect
}
const vehicle = vehiclesRef.current.get(event.data.id);
if (vehicle) onSelectRef.current(vehicle);
});
};
mass.on('click', selectMassPoint);
mass.setMap(map);
const labels = AMap.LabelsLayer ? new AMap.LabelsLayer({ zooms: [11, 18.99], zIndex: 110, collision: true, allowCollision: false }) : null;
const denseLabels = AMap.LabelsLayer ? new AMap.LabelsLayer({ zooms: [19, 20], zIndex: 110, collision: false, allowCollision: true }) : null;
labels?.setMap(map);
const notifyViewport = () => {
notifyViewport = () => {
setMapZoom(map.getZoom?.() ?? 5);
window.clearTimeout(viewportTimerRef.current);
viewportTimerRef.current = window.setTimeout(() => {
@@ -219,11 +227,12 @@ export function FleetMap({ vehicles, selectedVin, onSelect, monitorMap, onSelect
};
map.on?.('moveend', notifyViewport);
map.on?.('zoomend', notifyViewport);
map.on?.('dragstart', () => {
stopFollowing = () => {
if (!centeredVinRef.current) return;
followSelectedRef.current = false;
setFollowSelected(false);
});
};
map.on?.('dragstart', stopFollowing);
mapRef.current = map;
amapRef.current = AMap;
massRef.current = mass;
@@ -246,6 +255,12 @@ export function FleetMap({ vehicles, selectedVin, onSelect, monitorMap, onSelect
resizeObserver?.disconnect();
window.clearTimeout(resizeTimer);
window.clearTimeout(viewportTimerRef.current);
if (selectMassPoint) massInstance?.off?.('click', selectMassPoint);
if (notifyViewport) {
mapInstance?.off?.('moveend', notifyViewport);
mapInstance?.off?.('zoomend', notifyViewport);
}
if (stopFollowing) mapInstance?.off?.('dragstart', stopFollowing);
massRef.current?.setMap(null);
labelsRef.current?.setMap(null);
denseLabelsRef.current?.setMap(null);