[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f03VCHOl-kKgqpxKWQ4Hz8yJl-4SLsEmMLk_d8t9JpBE":3},{"item":4,"related":40},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":31,"sourceName":32,"sourceUrl":32,"status":33,"seoTitle":32,"seoDescription":32,"canonicalUrl":32,"isFeatured":34,"sno":35,"sortOrder":36,"publishedAt":37,"updatedAt":38,"createdAt":39},"a04c10a4-3fe8-4537-81bd-354103c1078f","article","WebGPU：浏览器为什么能跑 3D、滤镜和部分 AI","webgpu-browser-gpu-computing-explained","WebGPU 让网页能更直接地使用 GPU 做渲染与通用计算。本文从 CPU 与 GPU 的分工讲起，拆解适配器、设备、缓冲区、WGSL 着色器和命令队列，并说明什么时候并行计算真的值得。","浏览器里的 3D 游戏、照片滤镜、视频特效，甚至一部分端侧 AI 推理，都在做同一件事：把大量相似的小计算同时交给 GPU。以前网页主要通过 WebGL 接触 GPU，WebGPU 则提供了更现代、更明确的图形与通用计算接口。W3C 对它的定义很直接：WebGPU 暴露了在 GPU 上进行渲染和计算的 API。[WebGPU 规范](https:\u002F\u002Fwww.w3.org\u002FTR\u002Fwebgpu\u002Fall\u002F)\n\n![一块图形处理器](https:\u002F\u002Fcommons.wikimedia.org\u002Fwiki\u002FSpecial:FilePath\u002FGraphics%20Processing%20Unit.JPG)\n\n## GPU 快，不是因为它有一个更快的 CPU\n\nCPU 像一位很聪明的总管，擅长处理复杂、分支很多的任务；GPU 更像一座拥有大量工位的工厂，擅长让很多工位同时执行相似的步骤。\n\n把一张图片变成黑白图，每个像素都可以独立计算：读取红、绿、蓝三个通道，再按同一套公式得到灰度值。CPU 可以一个个像素处理，GPU 则能把成千上万个像素分发给并行执行单元。\n\n但“并行”不等于“所有任务都该上 GPU”。如果任务只有几次字符串拼接，调度 GPU 的准备成本反而可能比计算本身还高。WebGPU 的价值是让开发者能更直接地表达大批量、规则明确的工作。\n\n## 从 JavaScript 到 GPU，中间发生了什么\n\n一个 WebGPU 程序通常经过这条链路：\n\n1. 通过 `navigator.gpu` 请求适配器，了解浏览器能使用的 GPU 能力。\n2. 从适配器申请逻辑设备和命令队列。\n3. 创建缓冲区、纹理、采样器等 GPU 资源。\n4. 编写 WGSL 着色器，描述每个并行线程要做什么。\n5. 把计算或绘制命令编码出来，提交到队列。\n6. 等 GPU 执行完，再把结果显示到画布或读回 CPU。\n\n```mermaid\nflowchart LR\n    A[JavaScript 组织数据] --> B[创建 GPU 资源]\n    B --> C[WGSL 着色器]\n    C --> D[编码命令]\n    D --> E[提交到队列]\n    E --> F[GPU 并行执行]\n    F --> G[画布显示或读回结果]\n```\n\n这里最重要的概念不是“调用一个神奇函数”，而是资源和命令的边界。JavaScript 负责准备数据，着色器负责定义大量相同的计算，队列负责把命令送给 GPU。GPU 不会理解你的业务对象，它只看缓冲区、纹理和指令。\n\n## 着色器到底在写什么\n\n下面是一个简化的 WGSL 计算着色器。它让每个 GPU 线程把输入数组中的一个数字乘以 2：\n\n```wgsl\n@group(0) @binding(0)\nvar\u003Cstorage, read> input: array\u003Cf32>;\n\n@group(0) @binding(1)\nvar\u003Cstorage, read_write> output: array\u003Cf32>;\n\n@compute @workgroup_size(64)\nfn double_value(@builtin(global_invocation_id) id: vec3\u003Cu32>) {\n  output[id.x] = input[id.x] * 2.0;\n}\n```\n\n`global_invocation_id` 可以理解成当前线程的编号。线程 0 处理第 0 个元素，线程 1 处理第 1 个元素，彼此不需要等待。图像卷积、矩阵乘法和粒子模拟都可以用类似思想拆成大量小工作。\n\n当然，真正的性能取决于很多细节：数据是否连续、线程之间是否需要同步、显存访问是否规律、工作组大小是否适合硬件，以及 JavaScript 和 GPU 之间是否频繁搬运数据。把数据来回复制几次，可能轻易吃掉并行计算带来的收益。\n\n## WebGPU 和 WebGL 的关键区别\n\nWebGL 更接近“浏览器替你管理很多状态”的旧式接口。WebGPU 把设备、资源、绑定和命令编码讲得更清楚，允许浏览器在提交前做更严格的验证，也更贴近现代图形 API 的资源模型。\n\n这带来两面性：\n\n- 好处是状态更明确，复杂项目更容易组织，通用计算也更自然。\n- 代价是学习曲线更陡，要理解缓冲区、绑定组、管线和着色器。\n- 浏览器不能把底层 GPU 的所有细节原样暴露出来，所以仍然要经过权限、能力和安全验证。\n- 不同设备的 GPU 能力不同，不能默认所有格式、精度和特性都存在。\n\nWebGPU 也不是“在网页里直接运行 CUDA”。它是一套跨平台 Web API，浏览器会把它映射到系统可用的图形后端，同时限制资源访问，避免网页拿到任意设备内存。\n\n## 什么时候值得用\n\n最适合 WebGPU 的任务有三个特征：数据量大、单个元素的计算相似、结果能在 GPU 上连续使用。比如实时图像处理、粒子特效、3D 场景、矩阵运算和部分机器学习推理。\n\n如果页面只是渲染几十个按钮，WebGPU 是明显的过度设计。若任务需要频繁读取 GPU 中的每一个小结果，或者算法分支极多、数据量很小，CPU 可能更合适。工程上应先测量：上传数据、执行命令、同步等待和读回结果各花了多少时间，而不是只看 GPU 的理论算力。\n\n## 一份实用的落地清单\n\n- 把大数组和纹理尽量批量上传，减少频繁的小提交。\n- 让 GPU 上的计算形成连续流水线，避免每一步都读回 CPU。\n- 对设备能力做探测和降级，准备 WebGL 或 CPU 路径。\n- 将 WGSL 着色器当成独立模块测试，验证边界和越界访问。\n- 用浏览器开发者工具观察 GPU 时间，而不是用 JavaScript 函数耗时替代它。\n\n## 一句话带走\n\nWebGPU 的核心不是“网页终于有了一个更酷的画布”，而是浏览器开始允许你把一大批相似工作打包交给 GPU。真正的难点也从“能不能画出来”变成了“数据如何布局、什么时候同步、怎样让并行真的值得”。\n\n## 延伸阅读\n\n- [W3C WebGPU 规范](https:\u002F\u002Fwww.w3.org\u002FTR\u002Fwebgpu\u002Fall\u002F)\n- [GPU for the Web 工作组](https:\u002F\u002Fwww.w3.org\u002Fgroups\u002Fwg\u002Fgpu\u002F)\n- [WebGPU Shading Language 规范](https:\u002F\u002Fwww.w3.org\u002FTR\u002FWGSL\u002F)","\u002Fuploads\u002F2026-08-06\u002F05f26f06-cda2-4ed3-b1f2-5f26c82c2a37.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","f39339b1-aaa6-4e86-b0c2-a6e6a21113b5",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27],{"id":24,"name":25,"slug":26},"7c76bfc2-f80f-4ee0-a95d-27bd8708b434","技术","slug",{"id":28,"name":29,"slug":30},"4c2bbea6-eab7-40a8-8447-1de478ff7749","分析","analyse","资料来源",null,"published",false,62,0,"2026-08-06T00:00:00.000Z","2026-08-06T05:54:23.873Z","2026-08-06T05:38:22.834Z",[41,49,56],{"id":42,"type":6,"title":43,"slug":44,"summary":45,"coverUrl":46,"authorName":14,"sno":47,"publishedAt":37,"createdAt":48},"d6ff32b0-f499-453a-b1e3-c31a4a7a5b16","布隆过滤器：系统如何快速判断一个东西肯定不存在","bloom-filter-probabilistic-membership-explained","布隆过滤器用位数组和多个哈希函数，以极少内存快速筛掉肯定不存在的对象。本文讲清误报与漏报、误报率、删除难题，以及它在缓存、数据库和去重系统中的正确用法。","\u002Fuploads\u002F2026-08-06\u002F234915f6-2ef2-4820-8523-1a98544732f9.jpg",61,"2026-08-06T05:38:25.381Z",{"id":50,"type":6,"title":51,"slug":52,"summary":53,"coverUrl":54,"authorName":14,"sno":35,"publishedAt":37,"createdAt":55},"23cd6a50-6716-4620-99f3-d5307511c8ee","CRDT：两个人同时改同一段文字，为什么不会互相覆盖","crdt-collaborative-editing-explained","CRDT 允许多个副本先本地修改，再通过可合并的数据结构最终收敛。本文用计数器和协同编辑讲清 CvRDT、CmRDT、并发插入、删除标记、元数据成本与业务语义冲突。","\u002Fuploads\u002F2026-08-06\u002F50641649-08d8-4cac-94f0-647eabe9fc5f.jpg","2026-08-06T05:38:23.928Z",{"id":57,"type":6,"title":58,"slug":59,"summary":60,"coverUrl":61,"authorName":14,"sno":62,"publishedAt":37,"createdAt":63},"86b63309-e12a-41b4-9d9e-db95480617b0","令牌桶限流：API 如何把流量洪峰变成可控波浪","token-bucket-rate-limiting-explained","令牌桶把长期平均速率和短时突发容量分开，是 API 限流中最常见的模型之一。本文从令牌补充、请求成本和 429 响应讲起，比较固定窗口、滑动窗口与漏桶，并拆解分布式限流的真实难点。","\u002Fuploads\u002F2026-08-06\u002F952eedca-0e08-4c7c-a8a6-d07f1acd5291.jpg",63,"2026-08-06T05:38:26.532Z"]