节流是控制函数在指定时间间隔内最多执行一次的优化手段,核心是记录上次执行时间戳并判断是否超时,适合滚动、缩放等高频事件持续响应场景。

节流(throttle)是控制函数执行频率的常用手段,特别适合处理高频触发的事件(比如 scroll、resize)。它确保函数**在指定时间间隔内最多执行一次**,避免重复计算或重绘导致性能问题。
节流的核心逻辑
节流的关键在于:记录上一次执行的时间戳,每次触发时判断距离上次执行是否已超过设定的延迟(如 100ms),只有满足条件才真正执行函数,并更新时间戳。
- 不是“等停了再执行”,而是“固定节奏执行”
- 适合需要持续响应但不必每次都处理的场景(如滚动时更新吸顶状态、懒加载临界判断)
- 与防抖(debounce)不同:防抖是等“停顿后再执行”,节流是“匀速执行”
手写一个简单可靠的节流函数
下面是一个无依赖、易理解的实现:
function throttle(fn, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}
用法示例:
const handleScroll = throttle(() => {
console.log('滚动中,但每 100ms 最多触发一次');
}, 100);
<p>window.addEventListener('scroll', handleScroll);</p>
注意 this 和参数的正确传递
上面的实现用了 fn.apply(this, args),能保留原始调用上下文和所有参数。如果你用箭头函数或直接调用 fn(),可能丢失 this 或参数。常见错误写法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
fn()→ 丢失this和传入参数 -
fn.call(null, ...args)→this变成null,影响 DOM 方法调用(如event.target)
如果需要访问原生事件对象,建议在包装函数里接收并透传:
const handleScroll = throttle(function(event) {
console.log('滚动事件', event.target.scrollTop);
}, 100);
<p>window.addEventListener('scroll', handleScroll);</p>
使用 Lodash 的 throttle(推荐用于生产环境)
实际项目中更推荐用成熟库,比如 Lodash 提供了更健壮的 throttle,支持取消、立即执行、尾部执行等选项:
import { throttle } from 'lodash';
<p>const handleScroll = throttle(() => {
// 执行 DOM 操作或计算
}, 100, { leading: true, trailing: false });</p><p>window.addEventListener('scroll', handleScroll);</p><p>// 需要时可取消
// handleScroll.cancel();</p>
其中:
leading: true 表示首次触发立即执行;
trailing: false 表示结束时不补发最后一次(避免滚动停止后还执行)。
不复杂但容易忽略:节流只是优化手段,真正影响性能的往往是节流内部做的事——比如频繁查 DOM、强制同步布局(offsetTop、getBoundingClientRect)、或未做缓存的计算。节流 + 合理的内部逻辑,才是滚动优化的完整解。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










