Paint Worklet必须通过CSS.paintWorklet.addModule()异步加载同源独立JS模块注册,仅Chromium支持;registerPaint需在模块中调用,不可内联,无DOM访问能力,依赖CSS自定义属性传参。

不能靠直接写在 HTML 或 CSS 里生效,必须用 JavaScript 注册 + 异步加载 Worklet 模块,且仅 Chromium 系统(Chrome/Edge/Opera)支持。
registerPaint 必须在 Worklet 环境中调用
你写的绘制类(比如 WavePainter)不能放在主 JS 文件里直接执行 registerPaint;它必须被 CSS.paintWorklet.addModule() 加载进独立的 Worklet 线程后,才能运行。这个线程没有 window、document、fetch,也不能读取 DOM 节点。
常见错误现象:
- 把
registerPaint('wave', ...)写在普通<script>中 → 浏览器静默忽略,不报错也不渲染 - 在模块文件里调用
console.log→ 输出到 DevTools 的 “Worklet” 标签页,不是常规 Console - 试图用
import加载外部库(如 Lodash)→ 不支持,Worklet 是受限 JS 环境
CSS.paintWorklet.addModule() 是异步且不可重试的
调用 CSS.paintWorklet.addModule('paint.js') 后,浏览器会下载、解析、实例化一个新 Worklet 实例,但这个过程无法 await,也没有返回 Promise。重复调用同一路径会抛出 DOMException: Failed to execute 'addModule'。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 只调用一次,建议封装成幂等函数:
if (!window.__houdiniLoaded) { CSS.paintWorklet.addModule('paint.js'); window.__houdiniLoaded = true; } - 用
<link rel="preload" as="script" href="paint.js">提前触发下载,避免首次 paint 延迟 - 不要在模块加载完成前就设置
background: paint(wave),否则该声明会被浏览器丢弃(不报错)
自定义属性传参必须通过 inputProperties 声明
paint() 方法接收的参数只有三个:ctx(受限 Canvas2D)、geom({ width, height })、properties(CSS 自定义属性集合)。想让 JS 动态控制波幅、颜色、速度?只能走 --wave-amplitude 这类变量 + static get inputProperties() 显式声明。
关键细节:
- 未在
inputProperties列表里的变量,properties.get('--xxx')返回空值,不会报错 - 变量名大小写敏感,
--Wave-Amplitude和--wave-amplitude是两个不同变量 -
properties.get('--color').value返回字符串,需手动转类型:ctx.fillStyle = properties.get('--color').value || '#000' - 修改变量触发重绘是自动的,不需要手动刷新或调用任何方法
兼容性与降级必须手动处理
Firefox 和 Safari 当前(2026年9月)仍无启用 Paint API 的计划,CSS.paintWorklet 在它们内部是 undefined。别指望自动 fallback。
安全做法:
- 检测支持:
if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('paint.js'); } else { document.body.classList.add('no-houdini'); } - CSS 层降级:用
@supports (background: paint(dummy)) { ... }包裹 Houdini 专属样式,外部写传统 background 渐变或图片 - 避免在
<style>内联块中提前使用paint(wave)—— 若模块未加载,整条声明无效且不可捕获
最易被忽略的一点:Paint Worklet 的绘制结果是静态纹理,它不响应 transform、scale 或滚动位置变化;如果需要视差或缩放联动,得靠 JS 监听并主动修改对应 CSS 变量,而不是期望 Worklet 自动感知布局变动。


















