关于防抖和节流的三两理解

JS性能优化:防抖与节流
本文深入探讨了JavaScript中的性能优化技巧——防抖和节流。防抖技术确保在规定时间内仅执行最后一次操作,有效减少不必要的处理;而节流则限制操作的执行频率,确保在设定的时间间隔内只执行一次。通过代码示例,文章详细解析了两种技术的实现原理及应用场景。

前端开发其实必不可少的就是性能方面的优化了,合理的优化不仅加快了网络访问速度,同时也减少了系统内存的开销,然而不是每个人都能去大公司工作的,而有些小公司只会追求进度,对于性能方面难免不那么看中,至少在程序能够快速开发并且不崩溃的情况下,老板也不会让你再做什么优化了,让你做其他事缓解下开销岂不美滋滋?

但是这并不意味着我们不需要了解,毕竟这也是个有趣的方向,不是么?长话短说,let's go!

谈到js性能优化,防抖和节流就跃然脑海中了,那么防抖做了什么?节流又做了什么?

防抖:个人参考了许多人的解释,最终还是从字面意义上解释,防止抖动,为什么?

一般而言,防抖用于输入框的设计中,为了减少http的请求而出现(个人不太懂为什么),当我们不断输入多个字符时,实际上输入框内置的方法在不断监听输入的变化,并反馈而出,这样你就能形象的感觉到数据不断在抖动了,因此我这样解释

而防抖所做的也很简单:规定时间内,一切操作都在不断重置,直到规定时间结束前,执行最新的操作,换言之,就是N秒不管你点了几次,输入了几次,我只看最后那个操作:

function debounce(fn, time) {
    let timer = null;
    return function() {
        let args = arguments;
        if(timer) {
            clearTimeout(timer);
        }
        // 原理即是不断销毁异步事件,达到指定时间内刷新事件操作
        timer = setTimeout(() => {
             fn.apply(null, args);
        }, time);
    }
}

那节流呢?

有人说是在滚动时这样做,其实我个人感觉,只要满足一个条件:只要你觉得在某个时间内,某个操作只需要执行一次就ok了,那么使用它就绝对没错了,个人感觉使用场景应该是挺多的

看代码:

function throttle(fn, delay) {
    let init = Date.now();
    return function() {
        let args = arguments;
        let now = Date.now();
        if(now - init > delay) {
            fn.apply(this, args);
            // 重置初始化时间为当前时间,表明当前已实现了
            // 操作,因此下次再执行的时候就需要以当前时间判断为基准了
            init = now;
        }
    }
}

两者的区别其实也挺好区分的

防抖:N秒只执行最新的操作

节流:N秒只执行第一次操作

具体使用场景还是需要多多琢磨的,虽然代码不难,但是要运用的好需要下功夫,以上只是粗浅的理解,使用还需实践!!!

<think>我们正在处理用户关于JavaScript防抖节流的问题。用户希望理解两者的概念并学习实现方法。 根据提供的引用,我们可以总结如下: 防抖(debounce): - 概念:在事件被触发后,等待一段时间(延迟)再执行回调。如果在这段等待时间内事件又被触发,则重新开始计时。 - 应用场景:适用于连续触发的事件,但我们只关心最后一次触发后的结果。例如:输入框搜索建议(用户停止输入后才发送请求)、窗口大小调整(调整结束后再计算布局)等。 节流(throttle): - 概念:在一段时间内,无论事件触发多少次,只执行一次回调。即稀释回调的执行频率。 - 应用场景:适用于连续触发但需要控制执行频率的事件。例如:滚动事件(每隔一段时间检查位置)、按钮频繁点击(防止重复提交)等。 实现方法: - 防抖的实现:使用setTimeout,每次事件触发时清除之前的定时器,再重新设置一个新的定时器。 - 节流的实现:有两种常见方式:时间戳定时器。时间戳方式记录上次执行的时间,当前时间与上次执行时间间隔大于设定值则执行;定时器方式则是设置一个定时器,在定时器未执行前忽略后续触发。 引用中提供了多种实现方式,我们将结合引用内容给出代码示例。 另外,用户要求回答结构清晰,逐步解决问题,并生成相关问题。同时,注意在回答中引用的段落末尾添加引用标识。 因此,我们组织回答如下: 1. 解释防抖节流的概念,并说明区别。 2. 分别给出防抖节流的基本实现代码(参考引用中的代码,并确保语法正确)。 3. 提供一些应用场景的例子。 4. 生成相关问题。 注意:引用标识要自然地添加在引用内容的末尾。</think>### JavaScript 防抖节流:概念、区别与实现 #### 一、核心概念 1. **防抖(Debounce)** 当事件高频触发时,**只在停止触发后的指定时间执行一次**。若在等待期内再次触发,则重新计时。 *应用场景*:搜索框输入联想(用户停止输入后发送请求)、窗口 resize 事件(调整结束后计算布局)[^1][^4]。 2. **节流(Throttle)** 事件高频触发时,**固定时间间隔内只执行一次**,稀释执行频率。 *应用场景*:滚动加载(每 200ms 检测位置)、按钮防重复点击(提交后禁用 1 秒)[^2][^3]。 #### 二、核心区别 | **特性** | 防抖 | 节流 | |----------------|-------------------------------|-------------------------------| | **执行时机** | 停止触发后执行 | 固定间隔执行 | | **连续触发** | 重置等待计时器 | 忽略间隔内的触发 | | **适用场景** | 关注最终结果(如搜索) | 关注过程(如滚动)[^3] | --- #### 三、实现方法 ##### 1. 防抖基础实现(参考引用[4][5]) ```javascript function debounce(fn, delay) { let timer = null; return function(...args) { clearTimeout(timer); // 清除旧定时器 timer = setTimeout(() => { fn.apply(this, args); // 延迟执行 }, delay); }; } // 使用示例 const searchInput = document.getElementById('search'); searchInput.addEventListener('input', debounce(() => { console.log('发送搜索请求'); }, 500)); ``` ##### 2. 节流两种实现 **时间戳版**(立即执行)[^5]: ```javascript function throttle(fn, wait) { let lastTime = 0; return function(...args) { const now = Date.now(); if (now - lastTime > wait) { fn.apply(this, args); // 立即执行 lastTime = now; } }; } ``` **定时器版**(延迟执行)[^5]: ```javascript function throttle(fn, wait) { let timer = null; return function(...args) { if (!timer) { timer = setTimeout(() => { fn.apply(this, args); timer = null; // 执行后释放 }, wait); } }; } ``` --- #### 四、关键优化技巧 1. **参数传递**:使用 `apply` 确保回调函数的 `this` 参数正确(引用[4])。 2. **首尾执行控制**: - 防抖可扩展立即执行版本(如提交按钮需即时反馈) - 节流可组合时间戳+定时器实现首尾均执行 3. **性能调优**: - 滚动事件用节流时,间隔建议 100-200ms[^3] - 输入框防抖延迟通常 300-500ms --- #### 五、实际应用建议 1. **防抖适用**:验证输入格式、自动保存功能(停止操作后触发) 2. **节流适用**:mousemove 拖拽、无限滚动加载 3. **框架集成**: Vue 可使用 `lodash.debounce` 装饰器,React 推荐用 `useDebounce` Hook
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值