js-性能优化之防抖

在移动端开发中,存在这样一种交互方式–下拉刷新,下拉刷新一般用于刷新当前页,从而获取最新的数据。但是在实际使用过程中,用户习惯快速重复的进行下拉的操作。如果用户每进行一次下拉操作都发起请求,这无疑会非常浪费带宽,而且许多刷新是无效刷新,即返回的数据与当前原有的数据相同。这种场景是可以进行优化的,通过使用防抖函数,在用户第一次操作下拉刷新的时候触发,之后的n秒(1秒或2秒)不再触发下拉刷新的回调函数。

什么是防抖:所谓防抖,就是指触发事件 n 秒后才执行回调函数,如果在这 n 秒内又触发了事件,则重新设置定时器为n秒后执行回调函数。

使用场景:页面中的按钮连续点击触发事件、下拉刷新、input延迟验证等。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>性能优化-防抖</title>
    <style>
        #app {
            width: 100px;
            height: 100px;
            background-color: rgb(144, 165, 48);
            color: white;
            text-align: center;
            line-height: 100px;
        }
    </style>
</head>
<body>
    <div id="app">点我</div>
    <script>
        /**
 		* 防抖函数
 		* @param {Function} fn 事件对应的回调函数 
 		* @param {Number} wait 延迟执行时间 
 		* @param {Boolean} immediate 是否立即执行
 		* @returns 
 		*/
        function debounce(fn, wait, immediate = false) {
            let timer = null
            return function () {
                const self = this, args = arguments;
                // 清除之前定时器
                if (timer) clearTimeout(timer)

                // 是否立即执行
                if (immediate) {
                    // 如果还在处于等待时间内,则不执行回调函数,并重新计时
                    let callNow = !timer
                    timer = setTimeout(() => {
                        timer = null
                    }, wait)
                    // 超过了等待时间,则可以直接执行
                    if (callNow) fn.call(self, args)
                } else {
                    // 延迟执行
                    timer = setTimeout(() => {
                        fn.call(self, args)
                    }, wait)
                }
            }
        }

        let count = 0
        const app = document.getElementById('app')

		//不能使用箭头函数,否则通过防抖函数后,this会出现问题
        function mouseMove() {
            count++
            app.textContent = count
        }

        app.onmousemove = debounce(mouseMove, 1000) //不立即执行。使用场景:input延迟验证。
        app.onmousemove = debounce(mouseMove, 1000, true) //立即执行。使用场景:下拉刷新。

    </script>
</body>
</html>

上述代码解析:

防抖函数通过闭包特性将timer一直留存在内存中,每次调用debounce都会先清除之前的定时器,如果不清除,则之前的定时器会对之后的定时器产生影响。由于之前定时器可能是执行timer = null所以会导致timer结果不是预期结果。

之后判断是否立即执行回调函数

如果是立即执行回调函数,则需要判断是否timer是null,如果timer是null则执行回调函数;如果timer不为null,则定时器重新计时。

如果不是立即执行回调,则比较简单,只需每次执行防抖函数时重新设置定时器就行。

是null,如果timer是null则执行回调函数;如果timer不为null,则定时器重新计时。

如果不是立即执行回调,则比较简单,只需每次执行防抖函数时重新设置定时器就行。

延迟执行效果:
在这里插入图片描述
立即执行效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值