日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

防抖 节流_防抖节流与前端性能优化

發(fā)布時間:2025/3/11 HTML 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 防抖 节流_防抖节流与前端性能优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在我們?nèi)粘5拈_發(fā)中經(jīng)常會用到一些容易被反復觸發(fā)的事件。比如:scroll、resize、鼠標事件(mousemove,mouseover等)、鍵盤事件(keyup、keydown)。

頻繁觸發(fā)回調(diào)導致的大量計算會引發(fā)頁面的抖動甚至卡頓。為了規(guī)避這種情況,我們需要一些手段來控制事件被觸發(fā)的頻率。就是在這樣的背景下,throttle(事件節(jié)流)和 debounce(事件防抖)出現(xiàn)了。

“節(jié)流”與“防抖”的本質(zhì)

這兩個東西都以閉包的形式存在。

它們通過對事件對應的回調(diào)函數(shù)進行包裹、以自由變量的形式緩存時間信息,最后用 setTimeout 來控制事件的觸發(fā)頻率。

Debounce

防抖的概念其實是從機械開關(guān)和繼電器的“去彈跳”(Debounce)衍生 出來的,基本思路就是把多個信號合并為一個信號。

手機拍照也有相似的概念,在拍照的時候手如果拿不穩(wěn)晃的時候拍照,一般手機是拍不出好照片的,因此智能手機是在你按一下的時候連續(xù)拍許多張, 能過合成手段,生成一張,也就是我們平常說的HDR。翻譯成JS就是,事件內(nèi)的N個動作會被忽略,只有事件后由程序觸發(fā)的動作才是有效的。

將目標方法(動作)包裝在setTimeout里面,然后這個方法是一個事件的回調(diào)函數(shù),如果這個回調(diào)一直連續(xù)執(zhí)行,那么這些動作就一直不執(zhí)行。為什么不執(zhí)行呢,我們搞了一個clearTimeout,這樣setTimeout里的方法就不會執(zhí)行! 為什么要clearTimeout呢,我們就需要將事件內(nèi)的連續(xù)動作刪掉嘛!待到用戶不觸發(fā)這事件了。那么setTimeout就自然會執(zhí)行這個方法。那么這個方法用在什么地方呢,就是用于input輸入框架的格式驗證,假如只是驗證都是字母也罷了,太簡單了,不怎么耗性能,如果是驗證是否身份證,這性能消耗大,你可以隔170ms才驗證一次,或者更長的時間。這時就需要這個東西。或者你這個是自動校驗,需要將已有的輸入數(shù)據(jù)往后端拉一個列表,頻繁的交互,后端肯定耗不起,這時也需要這個,如隔350ms。下面我們來實際寫一個防抖:

//?fn是我們需要包裝的事件回調(diào),?delay是每次推遲執(zhí)行的等待時間
function?debounce(fn,?delay)?{
??//?定時器
??let?timer?=?null

??//?將debounce處理結(jié)果當作函數(shù)返回
??return?function?()?{
????//?保留調(diào)用時的this上下文
????let?context?=?this
????//?保留調(diào)用時傳入的參數(shù)
????let?args?=?arguments

????//?每次事件被觸發(fā)時,都去清除之前的舊定時器,這里是閉包,timer變量必須清除
????if(timer)?{
????????clearTimeout(timer)
????}
????//?設(shè)立新定時器
????timer?=?setTimeout(function?()?{
??????fn.apply(context,?args)
????},?delay)
??}
}

//?用debounce來包裝scroll的回調(diào)
const?better_scroll?=?debounce(()?=>?console.log('觸發(fā)了滾動事件'),?1000)

document.addEventListener('scroll',?better_scroll)

Throttle

節(jié)流的概念可以想象一下水壩,你建了水壩在河道中,不能讓水流動不了,你只能讓水流慢些。換言之,你不能讓用戶的方法都不執(zhí)行。如果這樣干,就是debounce了。為了讓用戶的方法在某個時間段內(nèi)只執(zhí)行一次,我們需要保存上次執(zhí)行的時間點與定時器。下面來實際寫一個節(jié)流:

//?fn是我們需要包裝的事件回調(diào),?interval是時間間隔的閾值????????由于是閉包,last值可以保存上次的觸發(fā)時間,不會重置為0if?(now?-?last?>=?interval)?{

用 Throttle 來優(yōu)化 Debounce

debounce 的問題在于它“太有耐心了”。試想,如果用戶的操作十分頻繁——他每次都不等 debounce 設(shè)置的 delay 時間結(jié)束就進行下一次操作,于是每次 debounce 都為該用戶重新生成定時器,回調(diào)函數(shù)被延遲了不計其數(shù)次。頻繁的延遲會導致用戶遲遲得不到響應,用戶同樣會產(chǎn)生“這個頁面卡死了”的觀感。

為了避免弄巧成拙,我們需要借力 throttle 的思想,打造一個“有底線”的 debounce——等你可以,但我有我的原則:delay 時間內(nèi),我可以為你重新生成定時器;但只要delay的時間到了,我必須要給用戶一個響應。這個 throttle 與 debounce “合體”思路,已經(jīng)被很多成熟的前端庫應用到了它們的加強版 throttle 函數(shù)的實現(xiàn)中:

//?fn是我們需要包裝的事件回調(diào),?delay是時間間隔的閾值
???????timer?=?setTimeout(

?如果覺得本文對你有所幫助,不如點個在看再走。

總結(jié)

以上是生活随笔為你收集整理的防抖 节流_防抖节流与前端性能优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。