WebGPU 是浏览器的新一代图形与计算 API,它把 GPU 的并行算力直接开放给前端。相比 WebGL 只能做渲染,WebGPU 还能运行通用计算着色器,让图像处理、数据并行和端侧 AI 推理在客户端秒级完成。本文用可运行的示例,带你从零跑通第一个 WebGPU 程序。
一、为什么前端需要 WebGPU
过去十年,浏览器里的硬件加速几乎等同于 WebGL。WebGL 基于 OpenGL ES 2.0 的古老模型,缺乏计算能力、难以利用多线程,也无法直接调度现代 GPU 的并行核心。当我们要在网页里做百万级数据的并行计算、实时视频滤镜或本地大模型推理时,WebGL 力不从心。
从时间线看,WebGL 1.0 在 2009 年定稿,彼时 GPU 还以固定渲染管线为主;而 WebGPU 规范在 2023 年才走向稳定,直接吸收了近十年 Vulkan / Metal / D3D12 的成熟设计。换句话说,WebGPU 不是 WebGL 的小修小补,而是一次底层范式的换代:它把「命令缓冲区、绑定组、管线对象、计算通道」这些原生图形 API 的核心概念,原汁原味地带进了浏览器。
WebGL 的三个时代局限
- 没有通用计算:WebGL 只能光栅化三角形,算不了任意并行任务;
- 驱动与状态机陈旧:隐式全局状态多,难以做现代渲染管线优化;
- 多线程受限:难以把工作均摊到 GPU 的多个计算队列。
WebGPU 由 W3C 联合苹果、谷歌、微软、Mozilla 设计,直接对齐 Vulkan / Metal / D3D12 的现代抽象。它带来的关键能力是计算着色器(Compute Shader)——这意味着浏览器第一次能像写 CUDA 一样做通用并行计算。关于前端性能的整体思路,可延伸阅读我们的前端性能优化实战。
二、三分钟跑通第一个 WebGPU 程序
WebGPU 的所有操作都围绕「适配器(Adapter)→ 设备(Device)→ 队列(Queue)」展开。适配器代表一块物理 GPU,设备是逻辑句柄,队列负责把命令提交给 GPU 执行。下面这段代码在任何支持 WebGPU 的浏览器里都能直接运行。
获取适配器与设备并配置画布
// 1) 请求 GPU 适配器(物理显卡)与逻辑设备
const adapter = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
if (!adapter) throw new Error("当前浏览器不支持 WebGPU");
const device = await adapter.requestDevice();
// 2) 获取画布上下文并配置
const canvas = document.querySelector("canvas");
const context = canvas.getContext("webgpu");
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format, alphaMode: "opaque" });
console.log("WebGPU 设备就绪:", device);注意 requestAdapter 可能返回 null——这正是特性检测的标准写法。生产环境里一定要先判断,再决定是否降级到 WebGL。开发时推荐用VS Code 的 WebGPU 调试扩展配合本地服务联调。
三、用计算着色器做并行计算
计算着色器是 WebGPU 区别于 WebGL 的灵魂。它用 WGSL(WebGPU Shading Language)编写,运行在 GPU 上,每个线程处理一份数据,天然并行。下面用一个「百万 float 并行相加」的例子说明完整链路。
WGSL 计算着色器
// 用 WGSL 写一个并行数组相加的计算着色器
@group(0) @binding(0) var<storage, read> a : array<f32>;
@group(0) @binding(1) var<storage, read> b : array<f32>;
@group(0) @binding(2) var<storage, read_write> out : array<f32>;
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id : vec3<u32>) {
let i = id.x;
out[i] = a[i] + b[i]; // 每个线程处理一个元素,天然并行
}WGSL 的 @workgroup_size(64) 表示每个工作组 64 个线程;@builtin(global_invocation_id) 给出全局线程编号。一百万个元素会被自动切成 16384 个工作组同时跑。
在 JS 里创建缓冲区并派发
// JS 侧创建缓冲区并派发计算
const N = 1 << 20; // 一百万个 float
const bufA = device.createBuffer({ size: N*4, usage: GPUBufferUsage.STORAGE });
const bufB = device.createBuffer({ size: N*4, usage: GPUBufferUsage.STORAGE });
const bufOut = device.createBuffer({ size: N*4, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC });
// ... 写入 a、b 数据后 ...
const module = device.createShaderModule({ code: wgslSource });
const pipeline = device.createComputePipeline({ layout:"auto", compute:{ module, entryPoint:"main" } });
const bindGroup = device.createBindGroup({ pipeline, entries:[
{ binding:0, resource:{ buffer:bufA } },
{ binding:1, resource:{ buffer:bufB } },
{ binding:2, resource:{ buffer:bufOut } },
]});
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();
pass.setPipeline(pipeline); pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(Math.ceil(N/64)); // 16384 个工作组
pass.end(); device.queue.submit([ encoder.finish() ]);整段逻辑和 CUDA / OpenCL 的 kernel 派发几乎一致:建缓冲区 → 绑定点 → 编码命令 → 提交队列。差别只是 WebGPU 把这套模型搬到了浏览器安全沙箱里。把这类重计算放进 Web Worker,再结合PWA 的离线能力,可以做出真正「离线也能算」的网页应用。
四、渲染管线:画一个旋转三角形
如果只做渲染,WebGPU 的渲染管线也比 WebGL 清晰:显式声明顶点/片元着色器、图元拓扑和输出格式,没有隐藏的全局状态。下面是最简渲染管线骨架。
// 顶点着色器 + 片元着色器,画一个旋转三角形
const vs = `
@vertex fn vmain(@builtin(vertex_index) i:u32) -> @builtin(position) vec4<f32> {
var p = array<vec2<f32>,3>( vec2(0.0,0.8), vec2(-0.8,-0.6), vec2(0.8,-0.6) );
return vec4(p[i], 0.0, 1.0);
}`;
const fs = `
@fragment fn fmain() -> @location(0) vec4<f32> { return vec4(0.2,0.6,1.0,1.0); }`;
const module = device.createShaderModule({ code: vs + fs });
const pipeline = device.createRenderPipeline({
layout:"auto",
vertex:{ module, entryPoint:"vmain" },
fragment:{ module, entryPoint:"fmain", targets:[{ format }] },
primitive:{ topology:"triangle-list" },
});每帧调用一次 context.getCurrentTexture() 拿到交换链纹理,录制渲染通道并提交,就能持续出图。相比 WebGL 的 drawArrays 黑盒,WebGPU 的管线对象可复用、可缓存,性能与可维护性都更好。
五、WebGPU / WebGL / 原生 CUDA 怎么选
| 维度 | WebGPU | WebGL | 原生 CUDA |
|---|---|---|---|
| 运行环境 | 浏览器/跨平台 | 浏览器/跨平台 | 需 NVIDIA 显卡+驱动 |
| 通用计算 | 支持计算着色器 | 不支持 | 原生支持,最强 |
| 上手成本 | 中(新 API) | 低(资料多) | 高(C++/驱动) |
| 适用场景 | 网页并行计算、可视化、端侧 AI | 传统 3D 渲染 | 超大规模训练/科学计算 |
结论很清晰:想在网页里做并行计算或现代渲染,优先 WebGPU;只是画个 3D 模型且要兼容老浏览器,WebGL 仍可用;需要训练大模型或做超算,那本就不是浏览器的职责,交给服务端容器化部署的 GPU 机器更合适。
六、真实落地场景
图像滤镜与视频处理
把视频帧上传到 GPU 纹理,用计算着色器逐像素处理(锐化、调色、超分),再回读到 canvas,能轻松做到 4K 实时。相比在 JS 里逐像素循环,GPU 并行版本通常快两个数量级。
端侧 AI 推理与数据可视化
WebGPU 已经成为浏览器端推理框架(如 ONNX Runtime Web、WebNN)的底层后端。结合Svelte 5 的细粒度响应式做大规模数据的实时可视化,可以把百万点位的图表流畅渲染出来,而 CPU 方案早就卡死了。
更进一步的玩法是「计算着色器 + 推理」的混合管线:先用 WGSL 在 GPU 上完成数据归一化、特征提取等预处理,再把张量直接喂给推理后端,全程不回 CPU,延迟可以压到毫秒级。对于需要私有化、低延迟的客服问答或图像审核场景,这套端侧方案比把数据上传云端更安全也更省钱。
七、兼容性判断与生产建议
| 检查项 | 推荐做法 |
|---|---|
| 特性检测 | 先 requestAdapter(),返回 null 再降级 WebGL |
| 浏览器支持 | Chrome/Edge 113+、Safari 18+、Firefox 已默认开启 |
| 长期维护 | 把 shader 与 JS 解耦,CI 用校验脚本做格式校验 |
| 安全 | 用户上传的模型只在 Worker 内执行,避免阻塞主线程 |
把构建与格式校验放进GitHub Actions 持续集成,能在每次提交时自动发现 WGSL 语法错误,避免把坏管线带上线。
八、上手清单
- 确认浏览器版本支持 WebGPU(访问 chrome://gpu 看状态);
- 用
requestAdapter做优雅降级; - 从计算着色器小例子(数组相加)理解并行模型;
- 再写渲染管线,把 shader 与 JS 分离管理;
- 重计算放进 Web Worker,避免卡住交互线程。
WebGPU 不是要取代 WebGL,而是把「浏览器里能用 GPU 算 anything」这件事真正落地。它让前端第一次拥有和原生应用同级别的并行算力,图像处理、可视化、端侧 AI 都会因此重写一遍。现在正是上手的好时机。




