渲染管理

渲染管理系统会告知渲染程序何时重新渲染 。它确保在修改块(例如设置字段值、 或添加了输入),则砌块的形状会更新以匹配。

何时需要护理

如果您属于以下情况,则需要与该系统交互:

  • 向 Blockly 添加修改区块形状的方法。
  • 向 Blockly 添加依赖于更新后的大小或位置的方法 提供了有关区块的信息

工作原理

  1. 自动加入队列。每当块被修改时,Blockly 都会将“队列”a 该区块的呈现方式一些将渲染加入队列的修改示例 分别是:

    • 设置字段的值
    • 添加或移除输入
    • 连接或断开子块
  2. 创建资源集。当一个块加入队列时,渲染管理系统 它会将它及其所有父块添加到一组 重新渲染。

  3. 请求回电。然后,渲染管理系统使用 requestAnimationFrame 请求回调。浏览器会在绘制当前帧之前调用此回调。

  4. 将集重新渲染(以树状结构)。调用 requestAnimationFrame 回调时,渲染管理系统会从叶子块到根块渲染集合中的每个块。这样可以确保在父块呈现之前,子块具有准确的尺寸信息,以便父块可以围绕其子块进行伸缩。

运作方式

如果等到重新渲染块直到绘制当前帧之前, 渲染管理系统来删除重复的渲染请求。如果始终立即呈现块,系统可能会不必要地连续多次呈现同一块。系统会对渲染请求进行批处理 只有在帧的状态变为 最终确定。删除重复渲染操作可显著提高 Blockly 的效率。

例如,将一个块插入另外两个队列 11 会渲染, 实际上出现了 3 次(每个块各一次)。性能提升了 3.6 倍。

使用方法

您通常不必在意渲染管理系统, 它会在您修改块时自动运行。但在某些情况下,您必须直接与它互动。

队列渲染

如果您要向 Blockly 添加一个应更新方块形状的新方法,则需要调用 BlockSvg.prototype.queueRender 以将方块渲染加入队列。

等待渲染完成

如果您要向 Blockly 添加需要更新大小或 定位信息,则应等待 renderManagement.finishQueuedRenders() promise。此 promise 会在所有已排队的渲染完成后解析,如果没有已排队的渲染,则会立即解析。

import * as renderManagement from './renderManagement.js';

function async myNewMethod() {
  block.somethingThatModifiesTheShape();
  // Await the promise.
  await renderManagement.finishQueuedRenders();
  myThingThatReliesOnPositioningInfo();
}

立即触发已加入队列的渲染

如果您要向 Blockly 添加一个新方法,该方法需要更新有关某个代码块的尺寸或定位信息,并且您无法等到下一个帧以等待任何渲染完成,则可以调用 renderManagement.triggerQueuedRenders 以强制立即执行所有已排队的渲染。

import * as renderManagement from './renderManagement.js';

function async myNewMethod() {
  block.somethingThatModifiesTheShape();
  // Trigger an immediate render.
  renderManagement.triggerQueuedRenders();
  myThingThatReliesOnPositioningInfo();
}

一般情况下,您不希望执行此操作,因为其性能较低。只有在延迟会导致用户体验不佳的情况下,才需要这样做。例如,插入标记需要定位信息,并且插入标记必须向用户提供即时反馈,以便触发即时渲染,这一点非常重要。

核心中还有一些位置会出于向后兼容的原因触发立即渲染。我们计划在 v11 中移除这些功能。