feat: 实现批量更新机器人数据的功能,优化渲染性能,减少渲染调用次数

This commit is contained in:
xudan 2025-08-20 19:05:34 +08:00
parent 0c44af67a0
commit 45b25ac9d3

View File

@ -76,17 +76,73 @@ const monitorScene = async () => {
// requestAnimationFrame ID便 WebSocket
let animationFrameId: number;
/**
* 批量更新机器人数据减少渲染调用次数
* @param updates 需要更新的机器人数据数组
*/
const batchUpdateRobots = (updates: Array<{ id: string; data: RobotRealtimeInfo }>) => {
if (!editor.value || updates.length === 0) return;
//
updates.forEach(({ id, data }) => {
const { x, y, active, angle, path: points, isWaring, isFault, ...rest } = data;
//
editor.value?.updateRobot(id, rest);
// refreshRobot
let processedPath: Array<{ x: number; y: number }> | undefined;
if (points?.length) {
//
const cx = x || 37; // X37
const cy = y || 37; // Y37
processedPath = points.map((p) => ({ x: p.x - cx, y: p.y - cy }));
}
//
const robotState = { active, isWaring, isFault, path: processedPath, angle };
if (Object.values(robotState).some((v) => v !== undefined)) {
editor.value?.setValue({ id, robot: robotState }, { render: false, history: false, doEvent: false });
}
});
//
const positionUpdates = updates.map(({ id, data }) => {
const { x, y, angle } = data;
if (isNil(x) || isNil(y)) {
return { id, visible: false };
} else {
const newX = x - 60;
const newY = y - 60;
const rotate = angle;
return { id, x: newX, y: newY, rotate, visible: true };
}
});
// 使Meta2D
positionUpdates.forEach((update) => {
editor.value?.setValue(update, { render: false, history: false, doEvent: false });
});
//
editor.value?.render();
};
/**
* 渲染循环函数
* 通过 requestAnimationFrame 以浏览器的刷新频率被调用
* 采用时间分片Time Slicing策略为每一帧的渲染操作设定一个时间预算frameBudget
* 避免单帧处理过多数据导致UI阻塞
* 新增批量渲染优化减少渲染调用次数
*/
const renderLoop = () => {
const frameBudget = 8; // 8ms
const startTime = performance.now();
//
//
const updates: Array<{ id: string; data: RobotRealtimeInfo }> = [];
//
while (performance.now() - startTime < frameBudget && latestRobotData.size > 0) {
// Map
const entry = latestRobotData.entries().next().value;
@ -94,23 +150,17 @@ const monitorScene = async () => {
const [id, data] = entry;
latestRobotData.delete(id);
const { x, y, active, angle, path, isWaring, isFault, ...rest } = data;
//
if (editor.value?.checkRobotById(id)) {
//
editor.value?.updateRobot(id, rest);
//
if (isNil(x) || isNil(y)) {
//
editor.value.updatePen(id, { visible: false });
} else {
//
editor.value.refreshRobot(id, { x, y, active, angle, path, isWaring, isFault });
}
updates.push({ id, data });
}
}
//
if (updates.length > 0) {
batchUpdateRobots(updates);
}
//
autoDoorSimulationService.processBufferedData(frameBudget, startTime);