debounce (防抖)
因頻繁執(zhí)行 DOM 操作, 資源加載等行為, 導(dǎo)致 UI 停頓甚至瀏覽器崩潰
- window 對象頻繁的
onresize,onscroll等事件 - 拖拽的
mousemove事件 - 資源加載的
load事件 - 文字輸入, 自動完成的
keyup事件
比如每次搜索框內(nèi)每輸入一下就會向服務(wù)器發(fā)送一個請求, 這樣既沒有意義, 也很浪費(fèi)資源
實(shí)際上我們更希望搜索框內(nèi)當(dāng)有一段時間內(nèi)沒有再發(fā)生輸入事件時, 此時再向服務(wù)器發(fā)送請求會更有利與頁面性能和緩解服務(wù)器壓力
function debounce(func, delay = 100) {
let timer = null
return function () {
let that = this
let args = arguments
clearTimeout(timer)
timer = setTimeout(() => {
func && func.apply(that, args)
}, delay)
}
}
throttle (節(jié)流)
節(jié)流分為時間戳和定時器版
節(jié)流單純的降低代碼執(zhí)行的頻率, 保證一段時間內(nèi)核心代碼只執(zhí)行一次
時間戳版和定時器版的節(jié)流函數(shù)的區(qū)別
- 時間戳版的函數(shù)觸發(fā)是在時間段內(nèi)開始的時候
- 定時器版的函數(shù)觸發(fā)是在時間段內(nèi)結(jié)束的時候
時間戳版
function throttle(func, wait = 100) {
let lastTime = 0
return function () {
let nowTime = new Date().getTime()
if (nowTime - lastTime > wait) {
func && func.apply(this, arguments)
lastTime = nowTime
}
}
}
定時器版
function throttle(func, delay = 100) {
let timer = null
return function () {
let that = this
let args = arguments
if (!timer) {
timer = setTimeout(() => {
func && func.apply(that, args)
timer = null
}, delay)
}
}
}
防抖與節(jié)流的區(qū)別
- 防抖: 在規(guī)定時間內(nèi)不再有新的調(diào)用后執(zhí)行一次函數(shù)
- 節(jié)流: 保證一段時間內(nèi)執(zhí)行一次函數(shù)