一、前言
为什么要做性能优化?性能优化到底有多重要?性能优化是为了提供更好的用户体验、加快网站加载速度、提高搜索引擎排名、节省服务器资源、适应多种设备和网络环境等方面的需求。通过不断优化性能,可以提高用户满意度、增加网站流量提高业务效果。
同时他也是一把双刃剑,有好有坏。好的一面就是可以提升网站性能,坏的就是代码复杂、配置较多,遵守的规则太多。而且并不是适用于所有的场景,个人建议谨慎使用性能优化或者说按需使用。
JavaScript 中常用的两种性能优化方式是节流与防抖。它们的作用是减少函数的执行次数,提高代码的性能。在这里会介绍防抖与节流的定义、原理和实现方法。
二、对防抖与节流的理解
什么是防抖(Debounce)
如图,防抖(Debounce)是指在事件被触发delay时间后再执行function回调函数,如果在这设置的delay时间内又被触发,则重新计时。这可以使用在些点击请求的事件上,避免多次点击向后端发送多次请求。
什么是节流(Throttle)
如图所示,节流(Throttle)是指在规定一个延迟时间delay,在这个时间内,只能有一次触发事件的回调函数执行,如果在同一个时间内触发多次事件,只有一次能生效。
三、防抖函数的应用
1.搜索框实时搜索:用户在搜索框中输入内容时,通常需要进行实时搜索,使用防抖函数可以延迟请求的发送,只在用户停止输入后一段时间才真正发送请求,避免过于频繁的向后台进行请求操作。
2.表单输入验证:在表单输入过程中,每次用户输入完信息后都可能触发验证操作。使用防抖函数可以延迟触发验证操作,只在用户完成输入后一段时间进行验证,防止一直频繁的进行验证操作。
3.鼠标移动事件:在一些特定的交互场景中,需要根据鼠标的移动进行相应的交互。防抖可以延迟鼠标移动的事件触发,当用户停止移动一段时间后再执行操作。
下面我们用实时搜索为例子,演示一下防抖的使用:
没有使用防抖优化的代码
<div class='box'>
没有进行防抖处理:<input type='text' id='demo'>
</div>
<script>
// 模拟与后台进行交互
function demo(){
console.log("request" + value)
}
let boxInput = document.getElmentById('demo')
boxIput.addEventListener('keyup',ev=>{
demo(ev.target.value)
})
</script>
上面的代码只要我们在input中输入文字就会触发请求,输一个字符就会触发一次请求,对用户或者开发者来说都是一个不好的体验而且会对资源造成不必要的浪费。
思索:我们可以想到用户或者开发输入文字时需要一段时间的,这样我们就可以定义再规定时间进行完整输入然后再进行请求。
使用防抖优化后
规则:我们规定在1000ms内输入文字都不会触发请求,而是在input停止输入后1000ms进行发送请求。
<div class="box">
输入事件进行防抖处理:<input type="text" id="demo">
</div>
<script>
// 模拟请求
function demo(value){
console.warn("request: " + value);
}
const inputBox = document.getElementById("demo");
inputBox.addEventListener("keyup",ev=>{
debounce(() => demo(ev.target.value), 1000);
})
</script>
从上面的代码可以看出,在1000ms内在input中来纳许输入文字不会触发请求,在input停止输入后1000ms后发送了请求。
原理:对输入频繁的input添加定时器进行计数,只要输入时机在指定时间内就不会去触发请求,请求是发生在指定时间间隔内。
四、节流函数的应用
1.页面滚动事件:页面进行滚动时,会一直频繁的触发滚动事件,就会一直进行请求。使用节流可以控制滚动事件的触发频率,避免过多的计算、渲染操作。可以很好的提高页面的性能以及流畅程度。
2.频繁的点击事件:当某个按钮进行频繁点击时,如果在每次点击都执行复杂的操作,会特别影响性能。这时就可以使用节流来限制函数的执行频率,达到优化性能的效果。
下面我们就用频繁点击按钮为例,来详细看一下节流的使用:
没有使用节流优化的代码
<button id="demo" style="margin: 50px;">点击按钮</button></button>
<script>
let value = 1
// 模拟请求
function req(){
console.warn("request: " + value++ + ", time: " + new Date());
}
const ele = document.getElementById("demo");
ele.addEventListener("click", (e) => {
req()
});
</script>
上面的代码我们能看出,只要点击按钮就会触发请求,点击几次就会触发几次请求,这样会对服务器造成极大的压力,还有可以会造成多次提交导致数据重复!!!
使用节流优化后
规则:1000ms内多次点击,只会进行一次请求。
思路:当多次点击按钮时,为了避免多次请求,做一个节流限制 在规定的时间(100ms)内,只会有一次点击成功并触发事件。
<button id="demo" style="margin: 50px;">点击按钮</button></button>
<script>
let value = 1
// 模拟请求
function req(){
console.warn("request: " + value + ", time: " + new Date());
}
const ele = document.getElementById("demo");
ele.addEventListener("click", (e) => {
throttle(() => req(), 1000)
});
</script>
上面的代码就实现了在1000ms内多次点击,只会成功一次并只会发送一次请求。
参考文档:
1. Lodash - 防抖
2. Lodash - 节流