为什么不做防抖和节流啊!

58 阅读3分钟

节流和防抖在前端性能优化方面具有举足轻重的作用。看过八股或者参加过面试的同学想必不用多说,都知道这-是个经常考察的内容。


什么是防抖:

防抖就是连续触发事件时只执行一次。比如连续点击表单提交按钮。如果不做防抖优化,会重复提交给服务端造成不小压力,如果是脚本的恶意进攻,危害不言而喻。如果做了防抖优化,在连续的事件中,仅仅触发一次。

那么如何实现防抖?

实现思路:

事件在触发一段时间后执行,如果在这段时间内再次触发,则重新计时。

<body>
    <button class="debounceBtn">防抖</button>
    <script>
        const debounceBtn = document.querySelector('.debounceBtn');
        function logger () {
            console.log('点击了一次');
        }
        debounceBtn.addEventListener('click', debounce(logger, 1000));
        function debounce (fn, delay) {
            let timer = null;
            return function () {
                if (timer) clearTimeout(timer);
                timer = setTimeout(() => {
                    fn.apply(this, arguments);
                }, delay)
            }
        }
    </script>
</body>

什么是节流?

听名字,节流就感觉和防抖不一样,防抖是无论如何都只执行一次,多少显得寒酸?节流,节省资源,节能限流。我不管你点了多久,我只在规定时间内执行一次。你点击60秒,我规定5秒执行一次,那就执行12次。

事件在固定时间间隔内最多执行一次,无论期间触发多少次。

实现思路:

初始时设置上次执行时间为0,第一次触发的时候,获取触发时间,如果(触发时间-上次触发时间)> 限制时间。就执行一次,并且更改上次触发时间,把这次触发时间赋值给上次触发时间,给下次触发使用。

<body>
    <!-- 节流:一段时间内执行一次 -->
    <button class="throttleBtn">节流</button>
    <script>
        const throttleBtn = document.querySelector('.throttleBtn');
        function logger(className) {
            console.log(`按钮${className}被点击了。`)
        }
        throttleBtn.addEventListener('click', throttle(logger, 1000))
        
        function throttle(func, wait) {
            let previous = 0 // 上一次执行的时间
            return function () {
                let now = Date.now()
                if(now - previous > wait) {
                    func.apply(this, arguments)
                    previous = now
                }
            }
        }
    </script>
</body>

应用场景:

防抖:无论连续多少次,只触发一次

表单提交

  • 用户可能会在短时间内多次点击提交按钮,导致表单被多次提交。通过防抖机制,可以确保表单在一定时间内只被提交一次。

搜索框输入

  • 在搜索框中输入文字时,每输入一个字符都会触发搜索请求,这会导致大量不必要的请求。通过防抖机制,可以在用户停止输入一定时间后再发送请求,从而减少请求次数。

窗口大小调整

  • 在调整浏览器窗口大小时,会触发大量的 resize 事件。通过防抖机制,可以在用户停止调整窗口大小一定时间后,再执行相关操作。

节流:节能限流,一段时间执行一次

滚动事件

  • 当用户滚动页面时,频繁触发 scroll 事件会导致性能问题。通过节流,可以限制处理 scroll 事件的频率,比如每隔 200 毫秒处理一次,从而提升页面的性能。

窗口大小调整

  • 当用户调整浏览器窗口大小时,频繁触发 resize 事件。通过节流,可以限制处理 resize 事件的频率,避免性能问题。

输入框输入

  • 在文本输入框中输入时,频繁触发 input 事件。通过节流,可以限制处理 input 事件的频率,减少不必要的处理。

鼠标移动

  • 处理鼠标移动事件(如绘图应用)时,可以通过节流限制处理 mousemove 事件的频率,从而减少计算量和提高性能。

API 请求

  • 在某些场景下,需要频繁发送 API 请求,比如实时搜索或数据同步。通过节流,可以限制请求的频率,避免服务器过载。