在前端开发中,优化网页性能和提升用户体验是至关重要的。为了实现这一目标,我们可以利用一些优化技术,其中防抖(Debounce)和节流(Throttle)是常用的技术手段。
防抖和节流的目的都是控制事件的触发频率,避免频繁触发导致的性能问题。它们通过限制事件处理函数的执行次数,从而减少不必要的计算和操作。
防抖和节流在不同的场景中有各自的应用。比如,在用户输入时,可以使用防抖来延迟触发验证或搜索操作,以避免频繁的输入导致的性能问题。而在滚动页面或者处理高频点击事件时,可以使用节流来限制触发频率,提升性能和流畅度。
了解和应用防抖和节流可以有效地优化前端应用的性能和用户体验。在实际开发中,我们可以根据具体的需求和场景选择合适的优化策略,并结合性能测试和用户反馈进行调优,以达到更好的效果。
现在需要一个input输入框,并且监听它的input事件。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>防抖title>
head>
<body>
<input type="text">
<script>
const inputEl = document.querySelector('input')
inputEl.oninput = function(e){
console.log(e.target.value)
}
script>
body>
html>
防抖的原理是,在事件触发后设定一个延迟时间,如果在延迟时间内再次触发了同样的事件,则重新计时。只有在延迟时间内没有再次触发事件时,才执行事件处理函数。这样可以确保事件处理函数只会在事件停止触发后执行一次,避免了频繁触发导致的性能问题。
了解原理后,开始实现防抖功能,我们准备一个防抖函数(debounce),它接收两个参数,一个是事件触发函数,另一个是延迟时间。因为input事件需要接收一个函数,所以我们在debounce函数里返回一个函数。
现在我们设置一个定时器timer,当调用这个函数时,首先判断是否存在这个定时器,存在的话进行清空,随后,将timer赋值,延迟delay分钟后执行函数。
const inputEl = document.querySelector('input')
const debounce = (fn,delay = 500) => {
let timer = null
return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
fn()
}, delay);
}
}
inputEl.oninput = debounce(function(e){
console.log('输入...')
},1000)
我们看到输入四次,只会在延迟1s后打印,成功实现了最基本的防抖功能。
当我们需要打印input框里的内容时,会发现报错。
发现参数无法获取,我们在函数内打印this,可以看到打印的是input元素。要想让函数获取参数,需要在内部的function接收一个args,并且通过apply改变this指向,接收参数。
const inputEl = document.querySelector('input')
const debounce = (fn,delay = 500) => {
let timer = null
return function(...args){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this,args)
}, delay);
}
}
inputEl.oninput = debounce(function(e){
// console.log('输入...')
console.log(e.target.value)
},1000)
节流的原理是,在一定的时间间隔内,只执行一次事件处理函数。当事件触发时,如果在时间间隔内已经执行过事件处理函数,则忽略该次触发。只有在时间间隔内没有执行过事件处理函数时,才执行一次事件处理函数。这样可以控制事件处理函数的执行频率,避免过多的计算和操作。
了解节流原理后,我们可以通过画图的方式更加清楚。
根据上图,我们很清楚地知道,只有当前触发时间与上一次触发时间间隔要小于延迟时间才去触发事件。
const inputEl = document.querySelector('input')
const thorrtle = (fn, delay = 500) => {
let startTime = 0
return function () {
let curTime = new Date().getTime()
let diff = delay - (curTime - startTime)
if (diff <= 0) {
fn()
startTime = curTime
}
}
}
inputEl.oninput = thorrtle(function () {
console.log(111)
}, 1000)
但是,当我们想要获取输入的内容时,会和上边防抖一样报错。我们还是使用apply绑定参数。
const inputEl = document.querySelector('input')
const thorrtle = (fn, delay = 500) => {
let startTime = 0
return function (...args) {
let curTime = new Date().getTime()
let diff = delay - (curTime - startTime)
if (diff <= 0) {
fn.apply(this,args)
startTime = curTime
}
}
}
inputEl.oninput = thorrtle(function (e) {
console.log(e.target.value)
}, 1000)