前端性能优化-节流(throttle)和防抖(debounce)

1.函数防抖和节流是优化高频率执行js代码的一种手段,js中的一些事件如浏览器的resize、scroll,鼠标的mousemove、mouseover,input输入框的keypress等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能

“节流”与“防抖”的本质:
这两个东西都以闭包的形式存在。它们通过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout来控制事件的触发频率。

2.什么是节流?

节流就是在让函数在特定的时间内只执行一次

function throttle(fn,delay){
    let valid = true
    return function() {
       if(!valid){
           //休息时间 暂不接客
           return false 
       }
       // 工作时间,执行函数并且在间隔期内把状态位设为无效
        valid = false
        setTimeout(() => {
            fn()
            valid = true;
        }, delay)
    }
}
/* 请注意,节流函数并不止上面这种实现方案,
   例如可以完全不借助setTimeout,可以把状态位换成时间戳,然后利用时间戳差值是否大于指定间隔时间来做判定。
   也可以直接将setTimeout的返回的标记当做判断条件-判断当前定时器是否存在,如果存在表示还在冷却,并且在执行fn之后消除定时器表示激活,原理都一样
    */

3.什么是防抖?

函数防抖有效的防止了一个函数被多次调用
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

//根据函数防抖思路设计出第一版的最简单的防抖代码:
function debounce(fn,delay){
    let timer = null //借助闭包
    return function() {
        if(timer){
            clearTimeout(timer) 
        }
        timer = setTimeout(fn,delay) // 简化写法
    }
}


// 用onmousemove测试一下防抖函数:
function testDebounce() {
    console.log('test');
}
document.onmousemove = () => {
    debounce(testDebounce, 1000);
}

3 函数防抖与节流的比较

相同点:

都可以通过使用 setTimeout 实现。
目的都是,降低回调执行频率。节省计算资源。
不同点:

函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout 和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能。
函数防抖关注一定时间连续触发的事件只在最后执行一次,而函数节流侧重于一段时间内只执行一次。

4.应用场景

4.1 函数防抖的应用场景
连续的事件,只需触发一次回调的场景有:

搜索框搜索输入。只需用户最后一次输入完,再发送请求
手机号、邮箱验证输入检测
窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
4.2 函数节流的应用场景
间隔一段时间执行一次回调的场景有:

滚动加载,加载更多或滚到底部监听
谷歌搜索框,搜索联想功能
高频点击提交,表单重复提交

你可能感兴趣的:(js)