用途:优化 WebGPU 应用性能,核心目标是减少每帧 JavaScript 侧的 CPU 开销与 GPU 状态切换。资料指出多数 WebGPU 应用受 CPU 限制,因此优化手段集中在逐帧命令提交成本上。
主要能力与做法:
- 管线与绑定组缓存:GPURenderPipeline、GPUComputePipeline、GPUBindGroup 均为不可变且构建昂贵,应在加载时创建一次并复用,禁止在帧循环内调用 createRenderPipeline 或 createBindGroup。
- 渲染束:用 device.createRenderBundleEncoder 录制一次命令子集,finish() 得到 GPURenderBundle,帧循环用 pass.executeBundles([bundle]) 重放。适用于静态或基本静态场景、同一命令序列跨帧不变、同帧多次绘制同一几何体(如 VR 双眼、级联阴影)。绘制列表每帧变化时不要用渲染束;列表固定但逐对象数据变化时,更新 uniform/storage 缓冲后重放同一束;绘制数量需变化时可用间接绘制配合计算通道写参数缓冲。
- 状态排序:按管线、再按绑定组排序绘制调用,减少 setPipeline/setBindGroup 切换。
- 缓冲子分配:把多个小 uniform 打包进一个缓冲,用动态偏移选择;布局需声明 hasDynamicOffset,偏移必须是 minUniformBufferOffsetAlignment(256)的倍数,逐对象结构步长需补齐到 256 字节。
- 工作组尺寸:@workgroup_size 乘积应为 32 或 64 的倍数,不确定时用 64;2D 图像用 (8,8),3D 用 (4,4,4);不得超过 maxComputeInvocationsPerWorkgroup(默认 256)。
- 时间戳查询:需先确认 adapter.features.has("timestamp-query") 并加入 requiredFeatures,用 GPUQuerySet 类型 "timestamp" 配合 timestampWrites 测量真实 GPU 通道耗时,再用 resolveQuerySet 拷回缓冲。
限制与警告:禁止在帧循环内创建管线或绑定组;绘制列表不变时禁止每帧重建渲染束;动态偏移必须是 256 的倍数;工作组乘积须为 32/64 倍数且不超上限;未确认特性支持前不得使用时间戳查询或 timestampWrites,否则 requestDevice 会被拒绝;禁止在逐帧渲染路径中 await mapAsync 或 onSubmittedWorkDone,应使用轮转暂存缓冲延迟一两帧读取结果。
适用版本:WebGPU 1.0-stable(Chrome 113+、Safari 26+、Firefox 141+)。资料另附 references/methods.md、references/examples.md、references/anti-patterns.md 及若干相关技能,具体内容暂未提供。