什么是防抖和节流? 有什么区别? 如何实现?

16 阅读3分钟

什么是防抖和节流

防抖和节流是两种常用的浏览器事件处理方法,主要是通过时间控制、减少事件触发频率,优化性能。

防抖和节流的区别

防抖(debounce)的原理是在一定时间内,多次触发同一个事件,只执行最后一次操作。如果设定的时间到来之前,又一次触发了事件,就重新开始延时。防抖主要应用于用户输入事件,如搜索框输入、手机号码和邮箱验证等,当用户停止输入后,才执行事件处理函数,减少不必要的请求次数和服务器负载。

节流(throttle)的原理是在一定时间内,多次触发同一个事件,只执行第一次操作。无论在固定时间内是否有事件触发,都会按照固定时间规律触发。节流主要应用于持续触发的事件,如页面滚动、鼠标移动等,确保在规定时间内一定会执行一次真正的事件处理函数,减轻服务器和客户端的负担。

防抖和节流分别适合的场景

防抖(debounce)适合的场景:

  1. 输入框实时搜索:在用户输入内容的过程中,使用防抖可以减少频繁的查询操作,提高性能。
  2. 按钮提交事件。
  3. 表单验证。

节流(throttle)适合的场景:

  1. 滚动事件:滚动事件会被频繁触发,如果在每一个滚动事件中都去执行复杂的操作,会导致页面卡顿,影响用户体验。这时可以使用节流来限制函数执行的频率。
  2. 监听窗口大小变化:当窗口大小频繁改变时,使用节流可以减少重复事件的触发,避免不必要的计算和渲染。
  3. 网络请求:对于需要连续发送请求的场景,比如滚动加载数据或自动完成搜索,可以通过节流来减少请求的次数,降低服务器压力。
  4. 定时器:定时器的回调函数执行频率有时可能会快过于预期,通过在回调函数中应用节流可以控制定时器执行次数,同时也可以节省计算资源。
  5. 滑动动画:在动画过程中,如果过度频繁刷新渲染,可能会造成闪烁和卡顿现象,使用节流可以限制重绘的次数,提高性能和用户体验。
  6. 计算鼠标的移动距离

总的来说,防抖和节流的主要思想都是通过时间控制、限制事件触发的次数,从而提高性能和用户体验。在实际开发中,需要根据具体的业务需求和性能要求选择合适的方法。

如何实现防抖和节流

1. 使用 Lodash 或其他工具库

Lodash 是一个流行的 JavaScript 工具库,它提供了很多实用的函数,包括防抖和节流函数。

1.安装lodash

npm install lodash
cnpm install lodash
yarn add lodash

2.在 Vue 组件中引入并使用防抖和节流函数

import { debounce, throttle } from 'lodash';  
export default {  
  methods: {  
    debouncedMethod: debounce(function() {  
      // 需要防抖处理的代码  
    }, 1000),  
    throttledMethod: throttle(function() {  
      // 需要节流处理的代码  
    }, 1000),  
    // ...  
  },  
  mounted() {  
    // 绑定事件监听器  
    window.addEventListener('resize', this.debouncedMethod);  
    window.addEventListener('scroll', this.throttledMethod);  
  },  
  beforeDestroy() {  
    // 组件销毁前移除事件监听器  
    window.removeEventListener('resize', this.debouncedMethod);  
    window.removeEventListener('scroll', this.throttledMethod);  
  }  
};

2. 全局扩展Vue原型

可以直接在Vue的原型上扩展防抖和节流方法,使得它们在整个 Vue 应用中都可以使用。

1.在main.js或其他入口文件中扩展Vue原型

import Vue from 'vue';  
import { debounce, throttle } from 'lodash';

// 扩展 Vue 原型  
Vue.prototype.$debounce = function(fn, delay) {  
  return debounce(fn, delay);  
};  

Vue.prototype.$throttle = function(fn, limit) {  
  return throttle(fn, limit);  
};  

//...

new Vue({  
  // ...  
}).$mount('#app');

2.在 Vue 组件中使用

export default {  
  methods: {  
    debouncedMethod: function() {  
      // 使用 this.$debounce 调用防抖函数  
      this.$debounce(function() {  
        // 需要防抖处理的代码  
      }, 1000)(); // 注意这里需要立即执行函数  
    },  
    throttledMethod: function() {  
      // 使用 this.$throttle 调用节流函数  
      this.$throttle(function() {  
        // 需要节流处理的代码  
      }, 1000)(); // 注意这里需要立即执行函数  
    },  
    // ...  
  },  
  // ...  
};