perf(monitor): reuse point animation buffers

This commit is contained in:
lingniu
2026-07-16 10:27:36 +08:00
parent 59f220885b
commit 77f12be63e
2 changed files with 84 additions and 38 deletions

View File

@@ -2,7 +2,7 @@ import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-libra
import { afterEach, expect, test, vi } from 'vitest';
import type { MonitorMapResponse } from '../../api/types';
import { wgs84ToGcj02, type AMapLike, type AMapMap, type AMapMassPoint } from '../../integrations/amap';
import { FleetMap, interpolateMassPoints, interpolateMassPointsByElapsed, massPointFingerprint, pointMoveDurationMs } from './FleetMap';
import { advancePointMotions, FleetMap, interpolateMassPoints, massPointFingerprint, pointMoveDurationMs, pointMoveFrameMs } from './FleetMap';
const setData = vi.fn<(data: AMapMassPoint[]) => void>();
const setStyle = vi.fn();
@@ -178,18 +178,28 @@ test('uses each protocol report interval with bounded fallbacks for point motion
});
test('advances each vehicle independently according to its report interval', () => {
const previous: AMapMassPoint[] = [
const points: AMapMassPoint[] = [
{ id: 'JT808', label: 'A', style: 0, lnglat: [0, 0] },
{ id: 'GB32960', label: 'B', style: 0, lnglat: [0, 0] }
];
const target: AMapMassPoint[] = previous.map((point) => ({ ...point, lnglat: [30, 30] }));
const frame = interpolateMassPointsByElapsed(previous, target, 10_000, new Map([
['JT808', 10_000],
['GB32960', 30_000]
]));
const pointArray = points;
const pointObjects = [...points];
advancePointMotions([
{ point: points[0], start: [0, 0], target: [30, 30], durationMs: 10_000 },
{ point: points[1], start: [0, 0], target: [30, 30], durationMs: 30_000 }
], 10_000);
expect(frame[0].lnglat).toEqual([30, 30]);
expect(frame[1].lnglat).toEqual([10, 10]);
expect(points[0].lnglat).toEqual([30, 30]);
expect(points[1].lnglat).toEqual([10, 10]);
expect(points).toBe(pointArray);
expect(points[0]).toBe(pointObjects[0]);
expect(points[1]).toBe(pointObjects[1]);
});
test('reduces animation frame frequency as fleet redraw pressure grows', () => {
expect(pointMoveFrameMs(1, 1)).toBe(100);
expect(pointMoveFrameMs(200, 10)).toBeLessThan(pointMoveFrameMs(800, 120));
expect(pointMoveFrameMs(2_000, 1_000)).toBe(220);
});
function amapMock(): AMapLike {
@@ -339,6 +349,8 @@ test('skips unchanged refresh redraws and smoothly moves points without replacin
expect(latest?.[0].lnglat).toEqual(wgs84ToGcj02(113.27, 23.13));
}, { timeout: 1_800 });
expect(setData.mock.calls.length).toBeGreaterThan(dataCalls + 1);
const animationFrameBuffers = setData.mock.calls.slice(dataCalls).map(([frameData]) => frameData);
expect(new Set(animationFrameBuffers).size).toBe(1);
expect(setStyle).toHaveBeenCalledTimes(styleCalls);
expect(removeLabels).toHaveBeenCalledTimes(removeCalls);
expect(addLabels).toHaveBeenCalledTimes(addCalls);