跳转到内容

预览性能和资源预算

剪辑器“卡”不一定是 GPU 帧率。打开素材可能卡在容器索引和网络,拖动可能卡在 seek 和 decoder,播放可能卡在效果和音频填充,导出还会受编码器和存储影响。

不要只用开发机上一段 5 秒视频看平均 FPS。至少建立下面的矩阵:

维度例子
设备桌面高配、桌面低配、目标移动设备
素材H.264 MP4、VP9 WebM、VFR、长 GOP、4K 原片
工程1080p30/4K30、轨道数量、字幕和 Material 数量
操作首帧、快速 scrub、连续播放、停帧、导出
指标p50/p95 延迟、丢帧、pending、内存峰值、导出倍率

把浏览器版本、OS、GPU、是否跨源隔离和素材 hash 一起记录,否则回归数据很难比较。

const preview = attachPreviewCanvas(session, canvas, {
quality: 'adaptive',
fit: 'contain',
adaptiveScales: [1, 0.75, 0.5, 0.35],
targetFrameMs: 1000 / 30,
});

推荐策略:

  • 拖动和播放默认 adaptive;
  • 复杂工程允许下降到 0.5 或 0.35;
  • 用户停止操作后恢复 full,用于停帧检查;
  • 4K 原片配尺寸合适的 proxy;
  • 每个主视图只保留最新 scrub;
  • 缩略图只生成视口附近,并支持取消。

4K Project 不等于主监看窗口也要实时渲染 4K。如果 Canvas 在页面上只有 960×540,使用 4K backing store 通常没有价值。

Retina 屏幕 DPR=2 时,像素数量是同尺寸 CSS 面积的 4 倍。可以按设备档位限制:

const preview = attachPreviewCanvas(session, canvas, {
quality: 'adaptive',
pixelRatio: Math.min(window.devicePixelRatio, 1.5),
});

pixelRatio 控制 Canvas 呈现表面的像素;renderScale 控制内部内容渲染比例。两者都会影响清晰度和成本,但作用位置不同。

const media = new ProductionMediaProvider({
maxCachedIndexes: 8,
maxCachedIndexBytes: 64 * 1024 * 1024,
maxConcurrentOperations: 4,
maxPendingOperations: 64,
});

查看压力:

const mediaStats = media.snapshot();
console.table({
active: mediaStats.activeOperations,
pending: mediaStats.pendingOperations,
indexMiB: mediaStats.cachedIndexBytes / 1024 / 1024,
});

Pending 持续增长时,先减少缩略图请求、使用 proxy 和合并 scrub。盲目提高并发会同时增加 decoder、网络、内存和 GPU 压力。

const session = await Aelion.createSession({
media,
maxPendingFrames: 2,
maxDiagnostics: 256,
});

完整帧评估默认最多 2 个 in-flight,适合 latest-wins 交互。Diagnostic 历史也有上限,避免打开数小时后日志数组无限增长。

不要用很大的 maxPendingFrames 解决慢渲染;它会让旧帧占用资源更久,拖动体验反而更差。

每条可见 visual 轨都可能增加合成工作;Material 还会增加 pass、纹理采样和中间表面。产品可以:

  • 对设备 tier 限制同时启用的重效果数量;
  • 在交互中旁路高成本效果,停下后恢复;
  • 用 Material 静态预算限制 node、depth、pass 和 texture sample;
  • 给第三方 Shader/WASM 更严格的单独预算;
  • 提供“预览效果开关”,但导出前明确显示最终效果仍会执行。
  • 长输出使用 OPFS;
  • Memory Sink 的 finalize 会再分配连续数组;
  • 导出时减少后台缩略图和波形任务;
  • 开始前估算 quota,失败后删除半成品;
  • 4K/长片超过设备预算时转 Remote Export;
  • 本地导出可以排队,不需要多个 Session 同时满载。

当前 Windows 参考机的真实 H.264/AAC MP4 全链路基线(输入解码 → render → audio → encode → mux → sink)为:1080p30 约 3.26× 实时,4K30 约 3.49× 实时;两个测量窗口的主线程 >50 ms Long Task 都是 0。结果来自 reports/baseline/performance-1080p30-chromium.json,只用于同环境回归, 不构成其他设备的 SLA。

持久恢复由 corepack pnpm report:recovery 单独验证:WebM/MP4 在 25%、50%、 90% 提交点中断后,FFmpeg 逐帧 MD5 和完整 PCM SHA-256 必须与无中断参考一致。 PCM 哈希包含 codec packet 的完整尾部填充;逻辑 A/V 末端按请求帧数计算,报告中的 codecPacketEndUscodecTailFrames 单独披露 packet 量化。corepack pnpm report:phase3:check 会同时拒绝低于 1.5× 的 4K 结果、任何 50 ms 以上的主线程 Long Task、重复渲染已提交帧或超过 1 ms 的逻辑 A/V 末端漂移。

const stats = session.getStats();
console.log(stats.compile);
console.log(stats.preview);
console.log(stats.player);
console.log(stats.export);

重点关注:

  • compile 是否命中增量更新;
  • preview requested/rendered/failed 和 pending;
  • 实际 backend、width、height、renderScale;
  • player dropped frames、errors 和 audio buffered frames;
  • export started/completed/failed/cancelled;
  • dispose 后 renderer、scheduler、audio、transport 是否终止。

Stats 更新频率可能很高。性能面板可以本地显示;遥测应每 10–30 秒聚合 p50/p95、最大 pending 和 drop ratio,不要每帧发网络请求。

至少循环执行:

  1. 打开和关闭多个工程;
  2. 快速拖动、seek、播放和暂停;
  3. 页面后台/前台切换;
  4. 多次成功、取消和故意失败的导出;
  5. 网络断开、quota 失败和 context lost;
  6. 记录操作前后资源是否回到稳定区间。

单次慢通常还能降质或提示;资源不回落会让两小时后的编辑器突然崩溃,是更危险的问题。