防抖和节流

防抖和节流JavaScript 中常用的两种性能优化方式。面试中我们也会经常碰到。它们的作用是减少函数的执行次数,以提高代码的性能。

什么是防抖?

防抖(Debounce)是指在事件被触发 delay 时间后再执行回调 function 函数,如果在这设置的 delay 时间内事件又被触发,则重新计时。这可以使用在些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。

(通俗易懂的理解:王者荣耀里面的回城按钮,重复触发会重新计时)

应用场景

  1. 搜索框实时搜索:当用户在搜索框中输入内容时,通常需要实时进行搜索。使用防抖函数可以延迟搜索请求的发送,只在用户停止输入一段时间后才真正发送请求,避免频繁的请求操作。
  2. 表单输入验证:在表单输入过程中,每次用户输入都可能触发验证操作。使用防抖函数可以延迟触发验证操作,只在用户输入完毕一段时间后进行验证,避免频繁的验证操作。
  3. 浏览器窗口调整事件:当用户调整浏览器窗口大小时,会触发resize事件。使用防抖函数可以延迟resize事件的触发,只在用户停止调整窗口一段时间后才执行对应的操作,避免频繁的计算和布局操作。
  4. 鼠标移动事件:在一些特定的交互场景中,需要根据鼠标的移动位置做出相应的交互。使用防抖函数可以延迟鼠标移动事件的触发,只在用户停止移鼠标一段时间后才执行相应的操作,避免过度频繁的操作。

场景一利用定时器实现基本思路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<div>
<input type="text" class="ipt">
</div>
<script>
let timerId = null
//键盘松开的时候触发
document.querySelector('.ipt').onkeyup = () => {
//防抖
//先清除上一个定时器,执行新的定时器
if (timerId !== null) {
clearTimeout(timerId)
}
timerId = setTimeout(() => {
console.log('防抖');
}, 1000)
}
</script>
</body>

按钮防重复点击实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
function send(){
console.log('我们好棒鸭!');
}
const btn = document.getElementById("btn");
btn.addEventListener("click",debounce(send,1000))

function debounce(send,time){
let name;
return function(){
if(name) clearTimeout(name) //name有值,说明上次定时器还没执行完,这时清除上次定时器
name = setTimeout(function(){
send()
}, time);
}
}
</script>

什么是节流?

节流(Throttle)是指规定一个单位时间(延迟 delay 时间),在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。比如,设置每1000毫秒最多执行一次回调函数,不论事件触发的频率有多高。

(通俗易懂的理解:王者荣耀里面的技能需要cd,触发一次后需要等cd冷却时间才能触发下一次)

应用场景

  1. 页面滚动事件:当用户滚动页面时,会频繁触发滚动事件。使用节流函数可以控制滚动事件的触发频率,避免过多的计算和渲染操作,提高页面的性能和流畅度。
  2. 窗口大小调整:当用户调整浏览器窗口大小时,会不断触发resize事件。使用节流函数可以限制resize事件的触发频率,以避免过度计算和布局操作。
  3. 频繁点击按钮:在某些场景下,点击按钮可能会触发重复的提交操作。使用节流函数可以限制按钮点击的触发频率,防止重复的提交。
  4. 动画场景: 避免短时间内多次触发动画引起性能问题
  5. 拖拽场景: 在某些场景下,频繁触发位置变动会造成性能问题,固定时间内只执行一次,防止超高频次触发位置变动
  6. 下拉加载、视频播放记录时间等等

定时器实现思路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<h1>规定时间内频繁按我我执行一次</h1>
<script>
let timerId = null
document.querySelector('h1').onmouseover = () => {
//节流
if (timerId !== null)
return
timerId = setTimeout(() => {
console.log('节流');
timerId = null
}, 2000)
}
</script>
</body>

总结

防抖:单位时间内,频繁触发事件,只执行最后一次。

​ 代码思路:利用定时器,每次触发先清除掉以前的定时器(重新开始)

节流:单位时间内,频繁触发事件,只执行一次。

​ 代码思路:利用定时器,等定时器执行完毕,才开始定时器(不被打断)

[lodash库](Lodash 简介 | Lodash中文文档 | Lodash中文网 (lodashjs.com))

开发中一般用lodash库,利用里面的debounce(防抖)和throttle(节流)来做的。

安装

通过 npm:

1
2
$ npm i -g npm
$ npm i --save lodash

从jQuery到Lodash

jQuery简介

jQuery是一个非常受欢迎的JavaScript库,它提供了许多便捷的DOM操作和AJAX功能。jQuery的核心设计思想是简化DOM操作,使得开发者可以更快地构建出功能强大的网页应用。

jQuery的核心概念包括:

  • 选择器:jQuery提供了许多选择器,用于选择DOM元素。这些选择器可以根据ID、类、标签名等来选择元素。
  • 链式操作:jQuery的方法是链式的,这意味着可以在同一行中调用多个方法。这使得代码更加简洁和易读。
  • AJAX:jQuery提供了AJAX功能,使得开发者可以轻松地发送和接收HTTP请求。

Lodash简介

Lodash是一个功能强大的JavaScript库,它提供了许多实用的工具函数,帮助开发者更高效地编写代码。Lodash的设计思想是提供一系列可复用的函数,以便开发者可以轻松地组合这些函数来实现各种功能。

Lodash的核心概念包括:

  • 函数式编程:Lodash鼓励使用函数式编程的思想,这意味着开发者应该尽量使用纯粹的函数,而不是修改状态。
  • 柯里化:Lodash提供了柯里化函数,这意味着开发者可以创建可重用的部分函数。
  • 链式操作:Lodash的方法也是链式的,这使得代码更加简洁和易读。

jQuery和Lodash的联系

jQuery和Lodash都是JavaScript库,它们的目的是提供一系列便捷的功能,以便开发者可以更快地构建出功能强大的网页应用。然而,它们的设计思想和核心概念是不同的。jQuery的设计思想是简化DOM操作,而Lodash的设计思想是提供一系列可复用的函数。