内存优化

阅读时间:2分钟更新于 2025-05-29 11:50
  • GPU 资源需要手动释放,请确保 player 不使用后被销毁
  • 内存问题成为互动应用最大的问题,过多使用动画会导致一系列问题,内存优化主要有以下手段,请仔细阅读。

目前内存优化的主要有以下几种:

销毁资源

在动画结束后,请调用 player.dispose() 销毁播放器,释放内存,否则一定会发生内存泄漏。

通过 getActivePlayers() 函数,可以获得当前没有被销毁的所有播放器,如果发现有未销毁的播放器,请排查代码逻辑。

渲染分级

通常情况下 Galacean Effects 默认所有元素都会在低端机渲染,某些特效(比如烟花)对于性能消耗比较大,低端机渲染可能会产生卡顿,这个时候可以通过渲染分级在不同设备上显示不同等级的元素。

设置渲染分级

在编辑器上对元素设置好渲染分级后,开发者可以给 Player 传入 renderLevel 参数来手动控制渲染等级。

// Galacean Effects 机型分为: B A S级,分别对应 B 低端机,A 中端机,S 高端机。
const renderLevelLow = 'B'; // 如果 renderLevel 被设置为B,会自动降级到 30FPS
const renderLevelMidum ='A';
const renderLevelHigh ='S'

// 开发者手动控制渲染哪些等级的元素
player.loadScene(url, { renderLevel: renderLevelHigh });
player.loadScene(url, { renderLevel: renderLevelMidum });
player.loadScene(url, { renderLevel: renderLeveLow });

有些时候我们在低端机仍需要有一个替代元素,比如高端机渲染炫酷的烟花,低端机用一张简单的贴图替代,或者低端机使用简单的烟花,这个时候就需要增加一个替代品。以烟花为例,将复杂的烟花设置为 A+ 渲染,同时复制这些元素,复制的元素设置为 B 渲染,减少 B 级烟花的最大粒子数目,这样就能在不同机器上看到不一样的烟花。

卸载纹理

如果你的页面会跳转到其他页面,并且是压栈跳转,那么你的页面内存会长期存在,这样接下来的页面会有很大的内存压力。在页面被压栈时,需要卸载纹理。卸载纹理的原理很简单,把 GPU 中的图片资源删掉,当页面重新回到前台时,走网络请求重新加载纹理。

function goApp(){
  player.pause({ offloadTexture:true }); // 卸载纹理,暂停播放
  startApp(appId); // 页面压栈
}

function onResume(){
  player.resume(); // 页面重新回到前台,恢复纹理,进行播放
}

由于页面在关闭前,同样的图片资源会走缓存,所以恢复纹理的时间会非常快,相当于利用了磁盘存储。

以下表格是图片数据存储位置,GPU和内存过大都会影响APP,磁盘缓存不会影响APP。

loadScene

play

pause

pause:

offloadTexture

resume

GPU

内存

磁盘

(安全)

页面如果没有压栈,用 pause 方法暂停播放器即可。

无论如何,在页面 unload 的时候,都需要销毁所有播放器,这样能在 GC 之前释放内存。

性能优化建议

  1. 同一个页面不要使用多个 Player,如果一定要用,请暂停其他 Player,只保留一个 Player 播放。
  2. 单合成播放情况时,Player 会自动销毁之前的合成,如果多合成播放,请手动销毁不需要的合成 composition.dispose(),避免内存叠加。
  3. 复杂的多页面情况,页面如果压栈,请暂停全部的播放器,页面回前台的时候再恢复,如果后续页面内存压力大,可以卸载纹理释放内存。
  4. 一旦页面同时存在的 Player 超过 8 个,Chrome 会自动销毁之前创建的 Player。
  5. CSS 动画不适合和大面积 Canvas 动画一起播放。
  6. 剪裁图片,移除重复图片,尽量减少图片尺寸大小。
  7. 网络条件允许的情况下使用压缩纹理。
Preview