From 0d1308b3b9ab36da47fd84e6f6b61ef9119f10ca Mon Sep 17 00:00:00 2001 From: xudan Date: Mon, 4 Aug 2025 16:59:13 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BE=AA=E7=8E=AF=E9=80=BB=E8=BE=91=EF=BC=8C=E9=87=87?= =?UTF-8?q?=E7=94=A8=E6=97=B6=E9=97=B4=E5=88=86=E7=89=87=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E6=8F=90=E5=8D=87=E6=80=A7=E8=83=BD=EF=BC=8C=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E6=B5=81=E7=95=85=E5=8A=A8=E7=94=BB=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/movement-supervision.vue | 31 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/pages/movement-supervision.vue b/src/pages/movement-supervision.vue index cd24606..da83b9c 100644 --- a/src/pages/movement-supervision.vue +++ b/src/pages/movement-supervision.vue @@ -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); };