前言
我们都知道,优化性能,提高用户体验一直都是前端要解决的问题,而 防抖 和 节流 则是最简单的方法,那我们就开始吧
概念和例子
防抖
指在一定时间内,多次触发同一个事件,只执行最后一次操作。也就是,比如说,某个事件是点击某个按钮的某段时间后触发的,而在这段时间内如果又点击的这个按钮,那么,时间则会重新计算,一直到这段时间耗尽。
我们来看一个 防抖 的例子(React):
export default function App() {
// 事件
const ajax = (content) => {
console.log(`正在发起${content}的请求`)
return null
}
// 防抖
const debounce = (fun, delay) => {
let timeout
return function() {
clearTimeout(timeout)
timeout = setTimeout(() => {
fun.apply(this, arguments)
}, delay)
}
}
const debunceAjax = debounce(ajax, 1000)
return (
<main>
<div>
防抖:<input onChange={e => debunceAjax(e.target.value)} />
</div>
</main>
)
}
当我们在input输入框不断输入时,他并不会一直打印console,而是当我们在停下输入的1秒后才会有输出,这就是 防抖。
比如说,当我们需要在页面大小改变时重新布局我们的页面,页面大小改变时window会触发resize,不断的调整浏览器窗口大小会不断的触发这个事件,这时候便能用到 防抖, 我们可以在页面大小保持不变的某段时间才开始重新布局,这样便舍去了中间从a宽到b宽的布局,当然能用到 防抖 的场景还有很多。
节流
在一定时间内,多次触发同一个事件,只执行第一次操作。
我们来看一个 节流 的例子(React):
export default function App() {
// 事件
const ajax = (content) => {
console.log(`正在发起${content}的请求`)
return null
}
// 节流
function throttle2(fn, delay) {
let canRun = true
return function() {
if (!canRun) return
canRun = false
setTimeout(() => {
fn.apply(this, arguments)
canRun = true
}, delay)
}
}
const throttleAjax = throttle2(ajax, 1000)
return (
<main>
<div>
节流:<input onChange={e => throttleAjax2(e.target.value)} />
</div>
</main>
)
}
当我们在input输入框不断输入时,它只会每隔1秒打印一次console,不管中途输入几次,在这段时间内,只会触发一次事件,这就是 节流
比如说,当我们需要点击一个按钮去获取某些数据也就是从后端请求数据时,如果不断点击这个按钮则会不断发起请求,这是我们不需要的请求,这时候便可以用 节流 来保证在相应时间内点击只会触发一次,当然 节流 的应用场景也很多
总结
可以自己运行一下,看看它们的区别
export default function App() {
// 事件或者某个请求
const ajax = (content) => {
console.log(`正在发起${content}的请求`)
return null
}
// 防抖
const debounce = (fun, delay) => {
let timeout
return function() {
clearTimeout(timeout)
timeout = setTimeout(() => {
fun.apply(this, arguments)
}, delay)
}
}
// 节流
const throttle = (fun, delay) => {
let last, deferTimer
return function() {
let now = +new Date()
if (last && now < last + delay) {
clearTimeout(deferTimer)
deferTimer = setTimeout(() => {
last = now
fun.apply(this, arguments)
}, delay)
} else {
last = now
fun.apply(this, arguments)
}
}
}
//节流的第二种实现方法
function throttle2(fn, delay) {
let canRun = true
return function() {
if (!canRun) return
canRun = false
setTimeout(() => {
fn.apply(this, arguments)
canRun = true
}, delay)
}
}
// const throttleAjax = throttle(ajax, 1000)
const throttleAjax2 = throttle2(ajax, 1000)
const debunceAjax = debounce(ajax, 1000)
return (
<main>
<div>
防抖:<input onChange={e => debunceAjax(e.target.value)} />
</div>
<div>
节流:<input onChange={e => throttleAjax2(e.target.value)} />
</div>
</main>
)
}