# 问题来源

因为要绘制机器人动画, 所以开启了 requestAnimationFrame 渲染 loop;

目前采取的策略是每次重新计算所有机器人的最新位置, 调用 removeChildren 函数全量移除后; 然后根据最新的数据 deviceMap 来重新创建精灵, 并添加到缓冲区进行渲染

现象是: 每次重新渲染, 内存都会增加, 虽然调用了 deviceContaner的 removeChildren 函数, 但是并没有销毁掉所有的设备精灵;

  • Container.removeChildren(): 从此容器中删除在开始索引和结束索引内的所有子项

  • Render.destory 是清除事件, 但是并未清除缓冲区 所以我们销毁的应该是 Container.destroy

# 问题分析

1.动态数据的渲染 来自于全量和增量推送, 由于全量数据每次推过来我们都处理, 并且会重新加载到缓冲区去渲染, 每次多推全量也会造成内存增加

2.目前渲染方案采用的是批量移除然后重新渲染, 这种方式在于移除图层子元素(精灵, 几何图形等)存在移除不干净的问题 所以渲染更新元素的方案是不是只能去修改图层子元素, 而不是先删除在重新渲染

# 问题解决方向

1.继续采用之前的方案, 重新绘制所有机器人精灵, 但是得完全销毁每个设备精灵, 但是全量移除会影响其他操作, 因为我们选中元素是从 精灵数据里面取的, 移除在渲染会造成点击地图在做碰撞检测的时候找不到元素

function Destroy() {
  // 清除每个contaner容器下的buffer数据
  // 清除帧回头函数
  // 清除画布
}
// PIXI
function RemoveChild() {
  let removedChilds: PIXI.DisplayObject[] = this.container.removeChildren();
  removedChilds.forEach((c: PIXI.DisplayObject) => {
    c.destroy({
      children: true,
      texture: false,
      baseTexture: false,
    });
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

2.不清除缓冲区数据, 只去修改精灵的属性, 但是我们现在的数据都在 dataManager 里进行维护, 所以渲染数据需要进行一下映射, 直接操作图层内部精灵属性

# 方案 2, 增量修改精灵的方式

1.获取全量数据, 渲染初始机器人 2.接受增量数据, 处理增量数据, 更改变化机器人的属性

  • 状态: 纹理
  • 位置: position.xy
  • 方向: rotation 3.调用引擎 render 方法

# gl实例

清空上下文

if (this.#engine.gl && !this.#engine.gl.isContextLost()) {
  this.#engine.gl.getExtension("WEBGL_lose_context").loseContext();
}
this.rootLayer.destroy(true);
1
2
3
4
Last Updated: 5/22/2024, 6:13:07 PM