函数节流通过限制执行频率优化滚动性能,时间戳版首次立即执行但可能遗漏末次,定时器版兼顾周期性与兜底执行,适用于滚动监听、懒加载等场景。

函数节流(Throttle)在滚动事件中,核心是限制函数执行频率——不是每次滚动都触发,而是固定时间间隔内最多执行一次。
为什么滚动事件需要节流
滚动时浏览器会高频触发 scroll 事件(每秒可能几十甚至上百次),若直接在里面做 DOM 操作、计算位置或发请求,极易造成卡顿、重绘压力大、CPU 占用飙升。节流通过“降频”,让逻辑只在合理节奏下运行,兼顾响应性与性能。
基础节流函数实现(时间戳版)
利用上一次执行的时间戳,判断是否达到设定间隔:
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}- 适合对“执行时机”要求不严格、希望尽快响应的场景(如首次滚动立刻执行)
- 缺点:连续快速滚动时,最后一次滚动可能被忽略(因未达间隔)
更稳健的定时器版节流
结合时间戳 + 定时器,确保最后一次触发也能被执行:
function throttle(func, delay) {
let timeoutId = null;
let lastTime = 0;
return function(...args) {
const now = Date.now();
const remaining = delay - (now - lastTime);
<pre class="brush:php;toolbar:false;">if (remaining delay) {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
func.apply(this, args);
lastTime = now;
} else if (!timeoutId) {
timeoutId = setTimeout(() => {
func.apply(this, args);
lastTime = Date.now();
timeoutId = null;
}, remaining);
}
}; }
- 保证至少每隔
delay执行一次,且不会遗漏结尾的调用 - 常用于监听滚动位置更新、懒加载临界判断等需“兜底执行”的场景
在滚动事件中实际使用示例
比如实现滚动时实时显示当前滚动高度,并防抖节流:
const handleScroll = () => {
console.log('当前滚动Y:', window.pageYOffset);
// 这里可加:判断是否进入视口、触底加载、吸顶导航等逻辑
};
<p>const throttledScroll = throttle(handleScroll, 100); // 100ms内最多执行一次
window.addEventListener('scroll', throttledScroll);</p>- 注意:节流函数返回的是新函数,要将它传给
addEventListener,而非原函数 - 如需销毁监听,保存引用后调用
removeEventListener(不能传匿名/节流后函数) - 现代项目中也可考虑用
IntersectionObserver替代部分滚动监听逻辑,更高效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











