高刷屏下需避免raf中读写布局属性、fixed元素嵌套滚动容器、dpr变更未响应及第三方组件强制同步回流,否则引发layout thrashing和渲染抖动。

高刷屏下 rAF 回调里写 top/left 会直接触发 layout thrashing
高刷屏(120Hz/144Hz)本身不增加卡顿,但放大已有布局抖动:每帧预算从 16ms 缩到 ~8ms,element.style.top = '10px' 这种操作在旧屏上可能勉强撑住,在高刷屏上几乎必然超时。浏览器不会因为屏幕刷新快就“加速” Layout 计算,它只按需执行,且每次读写交替都会强制同步回流。
必须把所有布局敏感属性移出 requestAnimationFrame 回调:
- ❌ 禁止设置
top、left、width、height、margin、padding - ✅ 改用
transform: translateX(10px)或transform: translateY(-5px)—— 合成器线程处理,不阻塞主线程 - ✅ 若需动态缩放,用
transform: scale(1.2),而非修改font-size或line-height
滚动容器内 fixed 元素在高刷屏上高频跳动
在 overflow: auto 容器里设 position: fixed,本质是违反 CSS 定位规范:fixed 应相对于视口,但局部滚动容器截断了定位上下文。高刷屏下这个修正逻辑被更频繁地触发,表现为元素位置每帧微偏、视觉抖动。
解决方案不是加 will-change: transform,而是重构定位路径:
- ❌ 不要把
position: fixed元素放在滚动容器内部 - ✅ 把它提到
body下,用 JS 动态计算其相对于滚动容器的视口坐标 - ✅ 或改用
position: sticky(注意 iOS Safari 对 sticky 在 overflow 容器内的支持不稳定) - ✅ 极端情况可用
transform: translateY()模拟固定效果,配合requestAnimationFrame同步 scrollY 偏移
DPR 变化未响应导致 canvas 渲染模糊 + 抖动
高刷屏设备(如 MacBook Pro 16"、iPad Pro)常伴随高 DPR(2x/3x),但窗口拖到外接显示器时 window.devicePixelRatio 可能突变,而 resize 事件不触发。若 canvas 缓冲区未重置,就会出现像素错位、光标虚化、内容一帧清晰一帧糊——这就是渲染层抖动。
关键动作不是监听 resize,而是监听 DPR 变更:
- ✅ 用
matchMedia('(resolution)')监听,而非仅靠window.addEventListener('resize', ...) - ✅ canvas 的
width和height必须重设为Math.floor(cssWidth * dpr),不能只靠style.width - ✅ 绘制前调用
ctx.scale(dpr, dpr),然后用逻辑坐标绘图;否则fillRect(0, 0, 1, 1)在 DPR=2 下只占 1 物理像素,肉眼不可见 - ⚠️ 注意:
getBoundingClientRect()返回的是 CSS 像素,用于 canvas 定位前必须乘以当前dpr
第三方组件偷偷读 offsetHeight 导致抖动放大
很多 UI 库(如某些 el-scrollbar、自定义 dropdown)在 mounted 或 onShow 阶段调用 el.offsetHeight 或 getBoundingClientRect(),且没做节流或批量读取。在高刷屏下,这些调用被高频 scroll/mousemove 触发,形成 layout thrashing 链式反应。
你无法删掉它们,但可以隔离影响:
- ✅ 把第三方组件包裹在
transform: translateZ(0)容器中,强制其独立图层,避免抖动扩散到整个页面 - ✅ 在父级滚动容器上加
will-change: transform,提前创建合成层 - ✅ 若该组件支持配置项,关闭其自动尺寸探测(如 antd 的
autoSize、element-plus 的popperOptions中禁用strategy: 'fixed') - ❌ 不要试图 patch 第三方代码里的
offsetHeight调用——容易破坏水合或动画状态
高刷屏优化的复杂点不在“怎么加 rAF”,而在识别哪些 DOM 操作在高帧率下会从“可接受”变成“不可容忍”。真正卡顿往往藏在你没写的那几行第三方代码里,而不是你自己写的动画逻辑中。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











