什么是防抖和节流?如何理解它们并在不同的场景条件下灵活运用?

07-11 1749阅读

🙋‍♂️ 什么是防抖和节流?

防抖(Debouncing)和节流(Throttling)是两种常见的性能优化技术,常用于控制某些操作(例如事件处理器)的频率,从而减少资源消耗并提高性能。

什么是防抖和节流?如何理解它们并在不同的场景条件下灵活运用?
(图片来源网络,侵删)

防抖(Debouncing)

防抖是一种在事件被触发后等待一段时间,如果在等待时间内没有再次触发该事件,则执行事件处理器。如果在等待时间内再次触发事件,则重新开始等待。常用于避免短时间内频繁触发的事件处理,例如窗口调整大小、搜索框输入等。

示例代码(JavaScript)
function debounce(func, wait) {
    let timeout;
    return function(...args) {
        const context = this;
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(context, args), wait);
    };
}
// 示例用法
window.addEventListener('resize', debounce(() => {
    console.log('Window resized');
}, 300));

在这个示例中,当窗口大小变化时,只有在窗口大小停止变化后的300毫秒,console.log('Window resized') 才会被执行。

📹 视频演示(video)

防抖视频

节流(Throttling)

节流是一种在一定时间间隔内只允许函数执行一次,无论该时间间隔内事件被触发了多少次。常用于控制高频率触发的事件处理,例如滚动、鼠标移动等。

示例代码(JavaScript)
function throttle(func, limit) {
    let lastFunc;
    let lastRan;
    return function(...args) {
        const context = this;
        if (!lastRan) {
            func.apply(context, args);
            lastRan = Date.now();
        } else {
            clearTimeout(lastFunc);
            lastFunc = setTimeout(() => {
                if ((Date.now() - lastRan) >= limit) {
                    func.apply(context, args);
                    lastRan = Date.now();
                }
            }, limit - (Date.now() - lastRan));
        }
    };
}
// 示例用法
window.addEventListener('scroll', throttle(() => {
    console.log('Window scrolled');
}, 1000));

在这个示例中,当窗口滚动时,console.log('Window scrolled') 最多每隔1秒执行一次。

📹 视频演示(video)

节流视频

🏁 总结

  • 防抖:在事件停止触发后的指定时间内执行函数。适用于需要等用户停止操作后再处理事件的场景。
  • 节流:在指定时间间隔内最多执行一次函数。适用于需要限制函数执行频率的场景。

    🙋‍♂️ 窗口滚动事件一定得用节流吗?不可以使用防抖吗?

    窗口滚动事件使用节流和防抖都可以,但取决于具体需求和效果。

    使用防抖处理滚动事件

    防抖会在用户停止滚动后的一段时间才执行函数,这在某些场景下是有用的,例如:

    • 仅在用户停止滚动时加载数据或执行某些操作。
    • 避免在滚动过程中频繁执行函数,而仅在滚动结束时执行。
      示例代码
      window.addEventListener('scroll', debounce(() => {
          console.log('Scroll event detected after scrolling stops');
      }, 200));
      

      在这个示例中,只有当用户停止滚动200毫秒后,console.log('Scroll event detected after scrolling stops') 才会被执行。

      使用节流处理滚动事件

      节流会在用户滚动过程中每隔一段时间执行一次函数,这在需要频繁更新页面内容的场景下非常有用,例如:

      • 实时更新滚动进度条。
      • 在滚动过程中动态加载数据(如无限滚动)。
        示例代码
        window.addEventListener('scroll', throttle(() => {
            console.log('Scroll event detected with throttling');
        }, 1000));
        

        在这个示例中,console.log('Scroll event detected with throttling') 会在用户滚动过程中最多每隔1秒执行一次。

        选择防抖还是节流

        • 防抖:适用于在用户停止滚动后执行操作。例如,停止滚动后加载更多内容或进行一次性计算。
        • 节流:适用于在滚动过程中需要持续执行操作。例如,实时更新界面元素或加载滚动区域内的内容。

          🏁 总结

          • 滚动停止后的操作:使用防抖。
          • 滚动过程中的持续操作:使用节流。

            根据具体需求选择适合的优化技术可以有效提高应用性能和用户体验。

            🙋‍♂️ Vue3组合式 + TypeScript 写法

            使用 Vue 3组合式 和 TypeScript语法, 实现窗口调整大小的防抖(debouncing)和滚动事件的节流(throttling)

            1. 窗口调整大小的防抖(Debouncing)

              

            Resize the window and check the console for debounced resize events.

            import { ref, onMounted, onUnmounted } from 'vue'; // 防抖函数 function debounce void>(func: T, wait: number) { let timeout: ReturnType; return function(this: any, ...args: Parameters) { const context = this; clearTimeout(timeout); timeout = setTimeout(() => func.apply(context, args), wait); }; } // 防抖处理函数 const handleResize = debounce(() => { console.log('Window resized (debounced)'); }, 300); // 注册和注销事件监听 onMounted(() => { window.addEventListener('resize', handleResize); }); onUnmounted(() => { window.removeEventListener('resize', handleResize); });

            2. 滚动事件的节流(Throttling)

              

            Scroll the page and check the console for throttled scroll events.

            Scroll content
            import { ref, onMounted, onUnmounted } from 'vue'; // 节流函数 function throttle void>(func: T, limit: number) { let lastFunc: ReturnType; let lastRan: number | undefined; return function(this: any, ...args: Parameters) { const context = this; if (!lastRan) { func.apply(context, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(() => { if ((Date.now() - lastRan) >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } }; } // 节流处理函数 const handleScroll = throttle(() => { console.log('Scroll event detected (throttled)'); }, 1000); // 注册和注销事件监听 onMounted(() => { window.addEventListener('scroll', handleScroll); }); onUnmounted(() => { window.removeEventListener('scroll', handleScroll); });

            说明

            1. 防抖(Debouncing):

              • 实现:当窗口大小调整事件触发时,handleResize 函数会在300毫秒内没有进一步的调整后才执行。
              • 用法:当用户调整窗口大小时,防止过多频繁地处理事件,提升性能。
              • 节流(Throttling):

                • 实现:handleScroll 函数会在每1秒内最多执行一次,以控制滚动事件处理的频率。
                • 用法:减少滚动过程中处理事件的频率,优化性能和用户体验。

            在 Vue 3 中使用 可以方便地处理生命周期事件,如组件挂载 (onMounted) 和卸载 (onUnmounted),以便正确地添加和移除事件监听器。

            当然,你可以将上面的防抖、节流函数进行封装公用方法,供组件或模块使用。

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]