
上个月,我花了整整 三天,在优化一个数据可视化页面。50,000 个数据点,页面卡到像幻灯片播放一样。
我当时已经做了“标准答案里的所有事”:
我当时还挺得意的。
然后,出于好奇——好吧,其实是绝望——我用 WebGPU 重写了核心渲染循环。
结果是:
👉 快了 23 倍。
不是 23%。
是 23 倍。
那种会让你第一反应是:
“是不是我量错了?”
然后意识到一个更残酷的事实:
我这几个月,可能一直在解决错误的问题。
真相是:WebGPU 已经悄悄上线了
当整个开发者社区还在把 WebAssembly 当作 Web 性能的终极未来时,WebGPU 已经悄无声息地:
- 上线了 Chrome
- 上线了 Safari
- 上线了 Firefox
而且它 不仅仅是为了图形更快。
它在做的事情是:
👉 彻底改变浏览器里“什么是可能的”。
一个没人愿意承认的问题
我们这些年一直在给自己讲一个很舒服的故事:
Web 应用慢,是因为 CPU 不够快。
于是我们:
- 优化 JavaScript
- 上 TypeScript 提高可维护性
- 性能不够就用 WebAssembly
但你真的低头看过自己的电脑吗?你有一块:
- 能每秒执行 万亿级运算
- 专门为并行计算设计的
- 极其强大的 GPU
而我们一直在用它来干嘛?
👉 画圆角、阴影、渐变。
这本身就有点荒谬。
现实是:
对于 绝大多数计算密集型任务
——图像处理、模拟、机器学习推理、数据变换
GPU 的算力是 CPU 的 几百倍。
而 WebGPU,第一次让我们能在浏览器里,真正用上这股力量。
先说清楚:WebGPU 到底是什么?
WebGPU 是一个 现代的图形 + 计算 API,允许你从 JavaScript 直接访问 GPU 的底层能力。
换句话说:
你写的代码,不再跑在 CPU 上,而是跑在显卡上。
关键不是“graphics”,而是:
compute(计算)
这是 WebGPU 和 WebGL 的本质区别。
- WebGL:为画图而生,计算是副产品
- WebGPU:从一开始就为计算 + 图形同时设计
一个非常直观的例子
假设你要处理一百万个数字:
- 每个 ×2
- 再 +10
- 再限制到 0~100 之间
CPU / WebAssembly 的方式(本质还是顺序)
function processData(input) {
const output = new Float32Array(input.length);
for (let i = 0; i < input.length; i++) {
output[i] = Math.min(Math.max(input[i] * 2 + 10, 0), 100);
}
return output;
}
即使你用 WebAssembly,本质上也只是 8~16 个 CPU 核心在干活。
WebGPU 的方式(数千核心并行)
const shaderCode = `
@group(0) @binding(0) var<storage, read> input: array<f32>;
@group(0) @binding(1) var<storage, read_write> output: array<f32>;
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
let i = id.x;
output[i] = clamp(input[i] * 2.0 + 10.0, 0.0, 100.0);
}
`;
在我的 M1 MacBook 上:
- CPU 处理 1000 万个 float:45ms
- WebGPU:1.2ms
而且数据越多,优势越夸张。
这不是理论性能。
这是实测。
那些“根本不是图形”的真实应用场景
1️⃣ 客户端数据处理
我们做过一个 IoT 数据看板:
- 时间序列
- 数据量 2GB
- 以前:每次筛选都要打 API
原因很简单:JavaScript 在前端算不动。
后来我们把聚合逻辑写成 WebGPU shader:
- 所有计算在浏览器完成
- 筛选 < 50ms
- 后端成本 直接降了 60%
2️⃣ 实时图像处理(不是滤镜那种)
朋友团队做工厂缺陷检测:
- 摄像头实时画面
- 原来:云端 ML API,按帧付费
- 延迟高、成本高
迁到 WebGPU 之后:
这不是 demo,这是 真·生产系统。
3️⃣ 物理模拟
我们原型过一个流体模拟:
- WebAssembly:5000 粒子就卡
- WebGPU:50 万粒子,60fps
直接改变了产品形态。
为什么这件事比 WebAssembly 更重要?
WebAssembly 确实厉害:
- 接近原生性能
- 能跑 C++ / Rust
- 对 CPU 密集任务非常好
但有一个现实几乎没人提:
你还是被 CPU 核心数限制着。
就算你把 WebAssembly 并行化做到极致,你也不过是在用 十几个核心。
而 GPU?
👉 几千个。
一个有点刺耳的观点
WebAssembly 可能在“心理上”害了我们。
- 给你 2~3 倍性能提升
- 让你感觉“性能问题解决了”
但真正的 10~100 倍 提升,一直就在那里。只是我们不去看。
学习曲线?有,但没你想的可怕
我不会骗你:
- WebGPU API 很啰嗦
- buffer、binding、pipeline 一堆概念
- shader 调试会让你怀念
console.log
我第一次在 JS 和 GPU 之间传数据,花了 非常尴尬的时间。
但这不是“无意义的复杂”。
这是 用显式控制,换取极致性能。
而且说句实在话:
如果你能理解 async / await
你就能理解 WebGPU 的执行模型
它不是更难,只是 不一样。
认真花一个周末,你能入门。
那你现在该做什么?
WebGPU 不是万能的:
- CRUD 应用?不用
- 表单站点?不用
- 落地页?更不用
但如果你的应用:
- 处理大量数据
- 有复杂可视化
- 做重复计算
- 原本你觉得“必须上后端”
👉 那你真的该看看 WebGPU。
最容易成功的场景
- embarrassingly parallel(完全可并行)
- 每个输出只依赖自身输入
比如:
真正的转变,不是技术,是认知
我们必须停止把 GPU 当成:
“那个画图的东西”
而开始把它当成:
浏览器里自带的超级并行计算引擎
工具已经到了。
Chrome / Edge / Safari 都支持。
Three.js、Babylon.js 已经接入。
生态在快速补齐。
那个不太舒服的真相
这些年我们:
都没错。
但我们一直在做的是:
榨干“顺序 CPU 执行”的最后一滴性能
WebGPU 做的事情完全不同。
它不是让 JS 更快。
也不是取代 WebAssembly。
它是让一整类问题:
从“这在浏览器里不现实”
变成“这太简单了”
如果 WebAssembly 是:
把桌面性能带到 Web
那 WebGPU 是:
把超级计算机,带到 Web
这不是 hype。
这是数学。
结尾问题(值得你认真想)
你现在这个应用里:
最耗计算的那一段代码,
真的跑在对的硬件上吗?
技术的边界正在被 WebGPU 重新定义,更多关于前端性能革新的深度讨论,欢迎来 云栈社区 交流分享。