javascript性能优化之debounce与throttle

javascript性能优化之debounce与throttle

消抖(debounce):

  • 当函数被调用后,n秒之后才会触发该函数,如果在此期间函数再次被调用,则重新开始计时,n秒之后才会触发该函数。

其作用是为了避免某个事件在短时间内连续触发从而影响性能,也可用于避免在一定时间内重复提交表单等。

节流(throttle):

  • 函数被调用后,立即触发该函数,在之后的n秒之内不能再次重复触发。

该函数可以用于限制浏览器scroll,mousemove等高频触发事件的触发频率

下面介绍debouncethrottle的实现方式

这两种方法在lodash里已经给封装好了,下面用原生js实现

debounce

利用闭包,设置一个timer:

  • 每次执行都clearTimeout(timer)
  • 每次执行设置timer = setTimeout()执行函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function debounce(func, delay) {
// 存储timer
let timer = null
return function() {
// 如果已经设置了 timer,将其清空,防止未执行的timer执行
clearTimeout(timer)
timer = setTimeout(()=> {

// delay后执行函数,使用es6语法,给函数传入参数
let args = Array.from(arguments)

// 传入this和参数
func.apply(this, args)

}, delay)
}
}

debounce实例

在input事件使用debounce,减少触发次数,这里设置延迟为1秒,是不是有点像搜索引擎的提示呈现

GIF

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<input type="text" placeholder="debounce"/>
<p>debounce test</p>
</body>
</html>

<script>
const input = document.querySelector('input')
const p = document.querySelector('p')
input.addEventListener('input', debounce(function(e){
p.innerText = e.target.value
}, 1000))


function debounce(func, delay) {
// 存储timer
let timer = null
return function() {
// 如果已经设置了 timer,将其清空,防止未执行的timer执行
clearTimeout(timer)
timer = setTimeout(()=> {

// delay后执行函数,使用es6语法,给函数传入参数
let args = Array.from(arguments)

// 传入this和参数
func.apply(this, args)

}, delay)
}
}

</script>

codepen

throttle

利用闭包,设置一个exec记录当前函数执行状态:

  • 若正则执行,则跳过if,直接退出函数
  • 若没有在执行,则执行函数,设置exec为true,一段时间后置为false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function throttle(func, delay) {
// 记录当前函数是否正在被执行
let exec = false
return function() {
// 如果该函数未在执行
if (!exec){
// 执行该函数
let args = Array.from(arguments)
func.apply(this, args)

// 设置执行为true
exec = true

// 在delayh后设置为false
setTimeout(()=>{
exec = false
}, delay)
}
}
}

throttle实例

这里同样使用上面的例子,看看有什么区别

  • 使用throttle,设置1秒只能触发一次

GIF

如果还看不出区别,请看下图

  • 使用debounce ,设置延迟为1秒

GIF

很明显了对吧

不过throttle一般不用于这里,一般用于scroll,mousemove等触发频率很高的事件,对其进行限制

codepen

以上就是对debounce和throttle的介绍,希望能帮助到大家

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×