性能优化之---防抖和节流

在前端开发中,防抖(Debounce)和节流(Throttle)是两种常用的性能优化技术,主要用于控制高频率触发的事件,避免过多的计算或操作影响性能。

一、防抖(Debounce)

1. 原理

防抖的核心思想是将多次执行变为最后一次执行,即当持续触发某个事件时,只在事件停止触发后的指定时间内执行一次回调函数。防抖主要用于减少在短时间内重复触发的操作。

2. 实现

实现防抖的关键是使用 setTimeout 来延迟执行回调函数,每次触发事件时都重新设置计时器,只有在指定时间内没有再次触发事件时,才会执行回调函数。

function debounce(func, wait) {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}

 

3. 应用场景
  • 搜索框输入:在用户停止输入后再发送请求。
  • 窗口大小调整:在用户停止调整窗口大小后再执行调整逻辑。
  • 表单验证:在用户停止输入后进行验证。

 

二、节流(Throttle)

1. 原理

节流的核心思想是在一段时间内只允许一次执行,即当持续触发某个事件时,在指定时间间隔内只执行一次回调函数。节流主要用于限制在一定时间内的执行次数。

2. 实现

实现节流的关键是通过 setTimeout 或时间戳来控制回调函数的执行频率。

使用时间戳实现
function throttle(func, wait) {
  let previous = 0;
  return function (...args) {
    const now = Date.now();
    if (now - previous > wait) {
      previous = now;
      func.apply(this, args);
    }
  };
}

 

使用 setTimeout 实现

function throttle(func, wait) {
  let timeout;
  return function (...args) {
    if (!timeout) {
      timeout = setTimeout(() => {
        timeout = null;
        func.apply(this, args);
      }, wait);
    }
  };
}

 

3. 应用场景
  • 滚动事件:在用户滚动过程中限制执行频率。
  • 页面缩放:在用户缩放页面时限制执行频率。
  • 按钮点击:在短时间内限制按钮的点击频率。

 

三、结合防抖和节流

在某些场景下,可能需要结合防抖和节流来实现更加精细的控制。例如,在用户输入过程中使用防抖来减少请求次数,同时使用节流来限制请求频率。

function debounceThrottle(func, wait, immediate) {
  let timeout, previous = 0;
  return function (...args) {
    const now = Date.now();
    const later = () => {
      timeout = null;
      if (!immediate) func.apply(this, args);
    };
    const callNow = immediate && !timeout;
    clearTimeout(timeout);
    if (now - previous > wait) {
      previous = now;
      if (callNow) func.apply(this, args);
    }
    timeout = setTimeout(later, wait);
  };
}

 

四、防抖和节流的对比

  • 防抖:确保在事件停止触发后的指定时间内只执行一次回调函数,适用于用户停止操作后的处理。
  • 节流:确保在指定时间间隔内只执行一次回调函数,适用于限制高频率操作的执行次数。

五、实际案例

 

搜索框输入防抖


<template>
<div>
<input type="text" v-model="query" @input="handleInput" placeholder="Search...">
</div>
</template>


<script>
import { debounce } from 'lodash';


export default {
data() {
return {
query: ''
};
},
methods: {
handleInput: debounce(function () {
console.log('Search:', this.query);
// 这里可以发送请求,获取搜索结果
}, 300)
}
};
</script>


滚动事件节流


<template>
<div @scroll="handleScroll" style="height: 400px; overflow-y: scroll;">
<div style="height: 1000px;">Scroll me!</div>
</div>
</template>


<script>
import { throttle } from 'lodash';


export default {
methods: {
handleScroll: throttle(function () {
console.log('Scroll:', window.scrollY);
// 这里可以处理滚动事件逻辑
}, 200)
}
};
</script>

 

 

结合防抖和节流的按钮点击


<template>
<div>
<button @click="handleClick">Click me</button>
</div>
</template>


<script>
import { debounceThrottle } from './utils'; // 前面定义的 debounceThrottle 函数


export default {
methods: {
handleClick: debounceThrottle(function () {
console.log('Button clicked');
// 这里可以处理点击事件逻辑
}, 500)
}
};
</script>

 

 

除了手动实现防抖和节流,市面上还有许多工具库可以帮助我们更方便地使用这些技术。最常用的库包括 Lodash 和 Underscore。

  • Lodash:一个现代 JavaScript 实用工具库,提供了包括防抖和节流在内的许多有用函数。

  • Underscore:一个提供类似功能的实用工具库。

 

posted @ 2024-07-22 17:17  最小生成树  阅读(4)  评论(0编辑  收藏  举报