前端面试相关:性能优化之防抖&节流

1,276 阅读5分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

防抖和节流是 JavaScript 中常用的两种性能优化方式。面试中我们也会经常碰到。它们的作用是减少函数的执行次数,以提高代码的性能。本文将详细介绍防抖和节流的定义、原理和实现方法,并讨论如何在具体功能中使用它们。

防抖

防抖是指在一定时间内,多次触发同一事件,只执行最后一次,或者只在开始时执行一次。防抖的应用场景比较广泛,例如在用户输入搜索关键词时,可以使用防抖来避免频繁地向服务器发送请求。

下面是一个简单的防抖实现代码:

/**
 * 防抖函数
 * @param {Function} fn - 需要执行的函数
 * @param {Number} delay - 时间延迟参数
 * @return {Function} 返回一个新的函数
 */
function debounce(fn, delay) {
  // 定义一个变量来保存定时器的返回值
  let timer = null;
  // 返回一个新的函数
  return function() {
    // 保存函数执行时的参数
    const args = arguments;
    // 如果已经存在定时器,则清除之前的定时器
    if (timer) clearTimeout(timer);
    // 创建一个新的定时器
    timer = setTimeout(() => {
      // 在延迟结束后执行传入的函数,并传入之前保存的参数
      fn.apply(this, args);
    }, delay);
  }
}

在这段代码中,我们定义了一个 debounce 函数,它接受一个函数 fn 和一个时间延迟参数 delay。返回一个新函数,在这个新函数中使用了闭包保存了原函数的 this 指向和 arguments 对象,以确保原函数在执行时能够正确地访问到它们。在延迟结束后执行原函数时,我们需要使用 apply 方法将保存的 this 指向传递给原函数,以确保它能够正确地访问到其所在的对象。

节流

节流是指在一定时间内,多次触发同一事件,只执行一次。节流的应用场景也比较广泛,例如在用户滚动页面时,可以使用节流来避免频繁地触发函数。

下面是一个简单的节流实现代码:

/**
 * 节流函数
 * @param {Function} fn - 需要执行的函数
 * @param {Number} delay - 时间延迟参数
 * @return {Function} 返回一个新的函数
 */
function throttle(fn, delay) {
  // 定义一个变量来保存定时器的返回值
  let timer = null;
  // 返回一个新的函数
  return function() {
    // 保存函数执行时的参数
    const args = arguments;
    // 如果已经存在定时器,则直接返回
    if (timer) return;
    // 创建一个新的定时器
    //fn.apply(this, args); //在延迟前执行传入的函数,并传入之前保存的参数
    timer = setTimeout(() => {
      // 在延迟结束后执行传入的函数,并传入之前保存的参数
      fn.apply(this, args);
      // 执行完毕后将定时器变量设置为 null,以便下一次调用函数
      timer = null;
    }, delay);
  }
}

在这段代码中,我们定义了一个 throttle 函数,它接受一个函数 fn 和一个时间延迟参数 delay。返回一个新函数,在这个新函数中使用了一个标记变量 timer 来判断是否需要执行原函数。在第一次调用原函数时,我们保存了其 this 指向和 arguments 对象,并且在计时器结束后执行原函数时,同样需要使用 apply 方法将保存的 this 指向传递给原函数,以确保它能够正确地访问到其所在的对象。

在具体功能中使用防抖和节流

防抖和节流的应用场景比较广泛,可以在很多具体功能中使用它们来提高代码的性能。例如:

  • 在用户输入搜索关键词时,可以使用防抖来避免频繁地向服务器发送请求。
  • 在用户滚动页面时,可以使用节流来避免频繁地触发函数。
  • 在监听窗口大小改变时,可以使用节流来避免频繁地调整布局。
  • 在监听鼠标移动时,可以使用节流来避免频繁地触发事件。

下面以一个搜索框的例子来演示如何在具体功能中使用防抖。

<input type="text" id="search-input">
const searchInput = document.getElementById('search-input');

function search(keyword) {
  console.log(`search for ${keyword}`);
  // 发送搜索请求
}

const debounceSearch = debounce(search, 500);

searchInput.addEventListener('input', event => {
  debounceSearch(event.target.value);
});

在这个例子中,我们首先定义了一个 search 函数,它会接受一个关键词参数并发送搜索请求。然后,我们使用 debounce 函数创建了一个新函数 debounceSearch,它会在输入框中输入内容时被调用,避免了频繁地向服务器发送请求。最后,我们通过 addEventListener 方法将这个新函数绑定到输入框的 input 事件上,以响应用户的输入。

类似地,我们也可以在其他具体功能中使用防抖和节流来提高代码的性能。只需要根据实际情况选择合适的函数和时间延迟参数即可。

结语

防抖和节流是 JavaScript 中常用的性能优化方式。它们的原理和实现方法都比较简单,但却能够显著提高代码的性能。在具体功能中使用防抖和节流也比较简单,只需要根据实际情况选择合适的函数和时间延迟参数即可。希望本文对大家有所帮助。