节流通过每16ms最多执行一次滚动处理,匹配60FPS刷新节奏,结合requestAnimationFrame实现精准调度,并配合硬件加速(transform/will-change)与剥离重操作,确保滚动流畅。
高频滚动时,浏览器每秒可能触发上百次 scroll 事件,若每次都执行 DOM 计算、样式更新或状态同步,主线程很快超载,帧率跌破 60FPS,用户立刻感知卡顿。函数节流不是“减少响应”,而是把密集事件“对齐到渲染节奏”,让逻辑只在合适时机运行。
浏览器理想刷新周期是 16.7ms(1000 ÷ 60)。节流将滚动处理限制在每 16ms 最多执行一次,正好匹配 requestAnimationFrame 的调度节奏。它不丢事件,也不等停止——而是“匀速采样”,确保视觉反馈连续、计算负载可控。
比 setTimeout 或时间戳轮询更可靠,因为它与屏幕刷新强绑定,不会因 JS 阻塞而错失帧。
requestAnimationFrame 内,交由浏览器统一调度offsetHeight),否则会触发同步重排示例代码:
<!-- 简洁、可复用的节流滚动处理器 -->let lastTime = 0;<br>window.addEventListener('scroll', () => {<br> const now = Date.now();<br> if (now - lastTime >= 16) {<br> requestAnimationFrame(() => {<br> // 这里放位置判断、class 切换、懒加载触发等轻量逻辑<br> updateStickyHeader();<br> lastTime = now;<br> });<br> }<br>});
节流解决“执行太密”,硬件加速解决“绘制太重”。两者必须配合:
transform: translateY() 替代 top 或 margin-top
will-change: transform,提前提示浏览器启用 GPU 图层width、height、left 等触发布局的属性节流只保“响应节奏”,不保“执行轻量”。以下操作即使节流了也会拖垮帧率,应彻底剥离:
Image.decode() + loading="lazy")