防抖与节流浅析

142 阅读1分钟

背景

事件频繁触发

  1. 浏览器事件:window.onresize、window.mousemove等,触发的频率如果过高,会造成浏览器卡顿
  2. 如果向后台发送请求,频繁触发,会对服务器造成很大的压力,甚至直接导致崩溃
  3. 连续请求返回的数据可能会叠加造成数据重复显示

解决方法

降低事件响应的频率:函数节流和函数防抖
函数节流
定义:
函数执行一次以后,只有大于设定的执行周期才会执行第二次,适合多次事件按时间平均触发
场景: 需要频繁响应的事件
窗口调整(resize)、页面滚动(scroll)、窗口拖拽(mousemove)、秒杀(click)

函数防抖
定义:
在规定的时间内,只有最后一次事件才响应,适合多次事件最后只一次响应的情况
场景: 不需要频繁响应的事件
搜索框输入联想(keyup/input)

示例代码

<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div class="container">
        <button type="button" id="throttleBtn">数据节流</button>
        <button type="button" id="debounceBtn">数据防抖</button>
        <script language="javascript">
            function throttle(func, delay) {
                let startDate = 0   // 首次点击响应
                let _this = this
                return function(...args) {
                    if (Date.now()-startDate>=delay) {
                        func.apply(_this, args)
                        startDate = Date.now()
                    }
                }
            }
            function debounce(func, delay) {
                let timer = null
                let _this = this
                return function (...args) {
                    timer&&clearTimeout(timer)
                    timer = setTimeout(()=>{
                        func.apply(_this, args)
                    }, delay)
                }
            }
            document.getElementById('throttleBtn').onclick = throttle(function(){
                console.log('数据节流')
            }, 3000)
            document.getElementById('debounceBtn').onclick = debounce(function () {
                console.log('数据防抖')
            }, 3000)
        </script>
    </div>
</body>
</html>