降级机制

阅读时间:3分钟更新于 2025-06-19 12:0

Tips:

  • 对于动效相关的业务,尽量都要准备动效降级方案,保证即使动效出问题也不影响业务功能。对于和动效紧密耦合的业务逻辑,在动效降级或者加载失败后,需要有兜底处理方案,否则会导致线上业务出问题。针对不同类型动效准备不同降级方案:
    • 对于简单动效,使用静态图替换;
    • 对于复杂动效,使用前端 CSS/SVG 动画替换(可以在导出面板选择“导出 SVG/CSS 动画”);
  • GE 编辑器在导出 Web 产物时,要确保设计师已经设置降级帧。
  • 代码中引入 降级插件

降级概述

为什么动效要做降级,因为在实际的业务场景中动效播放可能因为设备性能或兼容性问题而出错,也有可能只因为手机当前内存不够导致动效初始化失败或 webglcontextlost,因此,要做好动效加载或播放失败的准备,也就是要处理好动效降级的问题。

降级率

  • 简单动效(图层+3 粒子)FPS 稳定在 55 以上,设备覆盖率超 99%
  • 复杂动效设备覆盖率超 95%

Tips:

  • 以上数据是 2023 年亿级用户量日志分析得到。
  • 简单动效有 1% 覆盖不到的主要原因是设备不支持 WebGL,当然,随着设备的不断更新迭代,这个数据会逐年降低直至接近 0。
  • 复杂动效有 5% 覆盖不到的主要原因是设备的硬件性能不足,主要是会因为动效的复杂度带来渲染压力提升,从而会感觉卡顿甚至 Crash。
  • 对于非亿级体量的场景,理论不需要做降级的处理,使用“渲染分级”即可(详见:渲染分级-开发 渲染等级与机型开发示例)。

获取降级图

右键点击编辑器时间轴的帧指示线,即可设置当前帧为合成降级帧:

导出 Web 产物时会自动生成降级图:

downgrade文件夹中有降级的图片:

Tips:

  • 如果你不想用图片降级,可以通过导出 CSS 或 SVG 简单动画来做降级后的效果,比纯静态图好点。

降级示例

GE 2.0 开始,GE 降级插件提供 getDowngradeResult API 用于获取设备降级结果,可以在业务代码执行前进行调用,不需要先创建 Player 或 Canvas。

GE Player 降级能力整体上是基于运行设备硬件能力的评估,H5 是根据 navigator.userAgent 中的信息判断设备系统版本和硬件机型(iOS 无法直接获取硬件机型,可以通过屏幕大小估计机型,但准确性不够高,因为存在相同屏幕大小对应不同硬件机型的情况)。小程序可以通过 JSAPI 获取详细的机型、系统版本和性能指标。对于本地开发时需要 mock 降级的场景,可以设置 mockDowngrade,模拟没有降级(mockDowngrade: false)或被降级(mockDowngrade: true)的情况

1、安装 插件(请确保插件版本号与 @galcean/effects 版本号一致)。

$ npm i @galacean/effects-plugin-downgrade --save

2、获取降级结果并传入:

import { Player } from '@galacean/effects';
import { getDowngradeResult } from '@galacean/effects-plugin-downgrade';

// 通过 getDowngradeResult API,直接获取当前设备降级结果
const downgrade = getDowngradeResult({
  // 如果是小程序环境,会自动检测并调用 JSAPI 获取设备信息
  queryDeviceInMiniApp: true,
});

const player = new Player({
  // ...
  onError: (err, ...args) => {
    console.error('biz', err);
  }
});

const scene = await player.loadScene(json, {
  pluginData: {
    // 根据业务需求,传入对应的降级结果
    downgrade,
  },
});

getDowngradeResult 说明

根据传入的 DowngradeOptions,获取当前设备 GE 降级结果,不需要创建 Canvas 和 WebGL 环境。对于小程序环境,要确保 JSAPI 可以调用。外部调用时可以从返回的降级结果中获取 deviceInfo。外部也可以传入 deviceInfo,这样能够优化降级结果和提升降级精度。

用户也可以在外部直接判断当前设备是否需要降级,然后生成 DowngradeResult 结果,直接传给 loadScene

入参说明

  • level:可以指定返回的降级结果中渲染等级,不指定时会自动计算。
  • autoPause:禁用压后台的时候自动暂停播放器。
  • queryDeviceInMiniApp:在小程序环境下,是否自动通过原生 API 查询设备信息。
  • deviceInfo:设备信息,可以外部传入,没有传入时会自动获取。对于 H5 应用,通过 userAgent 只能获取非常简单的设备信息,需要精确降级是比较难做到的。如果能够通过特殊的 JSAPI 获取设备信息,并转成 deviceInfo 结构,就可以极大提升降级精度和准确性。
  • mockDowngrade:是否 mock 降级
    • true:mock 降级
    • false: mock 不降级
    • undefined: 不进行 mock, 用设备信息判断降级
  • downgradeCallback:自定义降级回调,可针对特定机型配置特定的降级规则

返回值说明

  • downgrade:是否降级
  • level:渲染等级
  • reason:降级原因
  • deviceInfo:设备信息

默认降级设备列表

OPPO R9s Plus
GM1910
V1824A
V1916A
SM-G9650
V1936A
MI9 PRO 5G
REDMI K20
V1914A
GM1900
RMX1971
SM-A6060
SM-G9600
V1922A
PBAM00
PCAM10
PACT00
PBBM00
PCEM00
V1818A
vivo X6A
vivo X6Plus A
  • 以上设备经过大体量数据验证,有些虽然能流畅运行,但是可能会有 Crash、渲染异常的情况。你可以使用 deviceInfo 动态添加其他设备或移除其中的型号。
  • 对于不同来源的硬件机型,例如:H5 的 navigator.userAgent 和小程序的 JSPAI,它们返回的机型名称可能会略有差别,如果要针对性配置,建议在真机环境中先进行测试,否则可能导致配置不生效。


Preview