refactor: 优化渲染循环逻辑,采用时间分片策略提升性能,确保流畅动画体验
This commit is contained in:
parent
0728911ef7
commit
0d1308b3b9
@ -76,18 +76,25 @@ const monitorScene = async () => {
|
||||
|
||||
/**
|
||||
* 渲染循环函数。
|
||||
* 这个函数会通过 requestAnimationFrame 以浏览器的刷新频率(通常是60fps)被反复调用。
|
||||
* 这是实现流畅动画的核心。
|
||||
* 通过 requestAnimationFrame 以浏览器的刷新频率被调用。
|
||||
* 采用时间分片(Time Slicing)策略,为每一帧的渲染操作设定一个时间预算(frameBudget),
|
||||
* 避免单帧处理过多数据导致UI阻塞。
|
||||
*/
|
||||
const renderLoop = () => {
|
||||
// 检查是否有新的数据需要渲染。如果没有,则本次循环不执行任何操作,节省性能。
|
||||
if (latestRobotData.size > 0) {
|
||||
// 遍历所有待更新的机器人数据
|
||||
latestRobotData.forEach((data, id) => {
|
||||
const { x, y, active, angle, path, isWaring, isFault, ...rest } = data;
|
||||
// 确保机器人仍然存在于编辑器中
|
||||
if (!editor.value?.checkRobotById(id)) return;
|
||||
const frameBudget = 8; // 每一帧的渲染预算,单位:毫秒。保守设置为8ms,为其他任务留出时间。
|
||||
const startTime = performance.now();
|
||||
|
||||
// 在时间预算内,持续处理数据
|
||||
while (performance.now() - startTime < frameBudget && latestRobotData.size > 0) {
|
||||
// 获取并移除 Map 中的第一条数据
|
||||
const entry = latestRobotData.entries().next().value;
|
||||
if (!entry) break;
|
||||
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);
|
||||
|
||||
@ -99,11 +106,11 @@ const monitorScene = async () => {
|
||||
// 如果坐标有效,则刷新机器人在画布上的位置、角度等
|
||||
editor.value.refreshRobot(id, { x, y, active, angle, path, isWaring, isFault });
|
||||
}
|
||||
});
|
||||
// 本次渲染完成后,清空数据缓冲区,等待下一批新数据的到来。
|
||||
latestRobotData.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// 请求浏览器在下一次重绘之前再次调用 renderLoop,形成动画循环。
|
||||
// 即使本帧没有处理完所有数据,下一帧也会继续处理剩余的数据。
|
||||
animationFrameId = requestAnimationFrame(renderLoop);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user