摘要:和的原理及實(shí)現(xiàn)和均是通過減少實(shí)際邏輯處理過程的執(zhí)行來提高事件處理函數(shù)運(yùn)行性能的手段,并沒有實(shí)質(zhì)上減少事件的觸發(fā)次數(shù)。兩者在概念理解上確實(shí)比較容易令人混淆,強(qiáng)制函數(shù)在某段時(shí)間內(nèi)只執(zhí)行一次,強(qiáng)制函數(shù)以固定的速率執(zhí)行。和等事件與此類似。
Debounce 和 Throttle 的原理及實(shí)現(xiàn)
throttle和debounce均是通過減少實(shí)際邏輯處理過程的執(zhí)行來提高事件處理函數(shù)運(yùn)行性能的手段,throttle并沒有實(shí)質(zhì)上減少事件的觸發(fā)次數(shù)。兩者在概念理解上確實(shí)比較容易令人混淆,
debounce 強(qiáng)制函數(shù)在某段時(shí)間內(nèi)只執(zhí)行一次,throttle 強(qiáng)制函數(shù)以固定的速率執(zhí)行。在處理一些高頻率觸發(fā)的 DOM 事件的時(shí)候,它們都能極大提高用戶體驗(yàn)。
在處理諸如 resize、scroll、mousemove 和 keydown/keyup/keypress 等事件的時(shí)候,通常我們不希望這些事件太過頻繁地觸發(fā),尤其是監(jiān)聽程序中涉及到大量的計(jì)算或者有非常耗費(fèi)資源的操作。
有多頻繁呢?以 mousemove 為例,根據(jù) DOM Level 3 的規(guī)定,「如果鼠標(biāo)連續(xù)移動,那么瀏覽器就應(yīng)該觸發(fā)多個連續(xù)的 mousemove 事件」,這意味著瀏覽器會在其內(nèi)部計(jì)時(shí)器允許的情況下,根據(jù)用戶移動鼠標(biāo)的速度來觸發(fā) mousemove 事件。(當(dāng)然了,如果移動鼠標(biāo)的速度足夠快,比如“刷”一下掃過去,瀏覽器是不會觸發(fā)這個事件的)。resize、scroll 和 key* 等事件與此類似。
1.debounce 函數(shù)所做的事情就是,強(qiáng)制一個函數(shù)在某個連續(xù)時(shí)間段內(nèi)只執(zhí)行一次,哪怕它本來會被調(diào)用多次。我們希望在用戶停止某個操作一段時(shí)間之后才執(zhí)行相應(yīng)的監(jiān)聽函數(shù),而不是在用戶操作的過程當(dāng)中,瀏覽器觸發(fā)多少次事件,就執(zhí)行多少次監(jiān)聽函數(shù)。function debounce(fn, delay) { // 定時(shí)器,用來 setTimeout var timer // 返回一個函數(shù),這個函數(shù)會在一個時(shí)間區(qū)間結(jié)束后的 delay 毫秒時(shí)執(zhí)行 fn 函數(shù) return function () { // 保存函數(shù)調(diào)用時(shí)的上下文和參數(shù),傳遞給 fn var context = this var args = arguments // 每次這個返回的函數(shù)被調(diào)用,就清除定時(shí)器,以保證不執(zhí)行 fn clearTimeout(timer) // 當(dāng)返回的函數(shù)被最后一次調(diào)用后(也就是用戶停止了某個連續(xù)的操作), // 再過 delay 毫秒就執(zhí)行 fn timer = setTimeout(function () { fn.apply(context, args) }, delay) } }
debounce 返回了一個閉包,這個閉包依然會被連續(xù)頻繁地調(diào)用,但是在閉包內(nèi)部,卻限制了原始函數(shù) fn 的執(zhí)行,強(qiáng)制 fn 只在連續(xù)操作停止后只執(zhí)行一次。
Throttlethrottle 的概念理解起來更容易,就是固定函數(shù)執(zhí)行的速率,即所謂的“節(jié)流”。正常
/** * * @param fn {Function} 實(shí)際要執(zhí)行的函數(shù) * @param delay {Number} 執(zhí)行間隔,單位是毫秒(ms) * * @return {Function} 返回一個“節(jié)流”函數(shù) */ function throttle(fn, threshhold) { // 記錄上次執(zhí)行的時(shí)間 var last // 定時(shí)器 var timer // 默認(rèn)間隔為 250ms threshhold || (threshhold = 250) // 返回的函數(shù),每過 threshhold 毫秒就執(zhí)行一次 fn 函數(shù) return function () { // 保存函數(shù)調(diào)用時(shí)的上下文和參數(shù),傳遞給 fn var context = this var args = arguments var now = +new Date() // 如果距離上次執(zhí)行 fn 函數(shù)的時(shí)間小于 threshhold,那么就放棄 // 執(zhí)行 fn,并重新計(jì)時(shí) if (last && now < last + threshhold) { clearTimeout(timer) // 保證在當(dāng)前時(shí)間區(qū)間結(jié)束后,再執(zhí)行一次 fn timer = setTimeout(function () { last = now fn.apply(context, args) }, threshhold) // 在時(shí)間區(qū)間的最開始和到達(dá)指定間隔的時(shí)候執(zhí)行一次 fn } else { last = now fn.apply(context, args) } } }
兩者應(yīng)用之后,直接帶來的效率。如果還是不能完全體會 debounce 和 throttle 的差異,可以到 這個頁面 看一下兩者可視化的比較。
參考地址
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/96095.html
摘要:淺談以及的原理和實(shí)現(xiàn)背景日常開發(fā)中我們經(jīng)常會遇到一些需要節(jié)流調(diào)用或者壓縮調(diào)用次數(shù)的情況例如之前我在完成一個需求的時(shí)候就遇到了因?yàn)楹蠖瞬l(fā)問題導(dǎo)致收到多條信息從而導(dǎo)致函數(shù)被重復(fù)調(diào)用的情況當(dāng)時(shí)的做法是通過對函數(shù)的調(diào)用進(jìn)行注冊遇到多次調(diào)用的時(shí)候清 淺談throttle以及debounce的原理和實(shí)現(xiàn) 背景 日常開發(fā)中,我們經(jīng)常會遇到一些需要節(jié)流調(diào)用,或者壓縮調(diào)用次數(shù)的情況,例如之前我在完成...
摘要:若時(shí)間差大于間隔時(shí)間,則立刻執(zhí)行一次函數(shù)。不同點(diǎn)函數(shù)防抖,在一段連續(xù)操作結(jié)束后,處理回調(diào),利用和實(shí)現(xiàn)。函數(shù)防抖關(guān)注一定時(shí)間連續(xù)觸發(fā)的事件只在最后執(zhí)行一次,而函數(shù)節(jié)流側(cè)重于一段時(shí)間內(nèi)只執(zhí)行一次。 原博客地址,歡迎star 函數(shù)防抖和節(jié)流 函數(shù)防抖和函數(shù)節(jié)流:優(yōu)化高頻率執(zhí)行js代碼的一種手段,js中的一些事件如瀏覽器的resize、scroll,鼠標(biāo)的mousemove、mouseover...
摘要:但是,我在測試中,智能手機(jī)中的慢速滾動可能會觸發(fā)每秒多達(dá)個事件。把電梯完成一次運(yùn)送,類比為一次函數(shù)的執(zhí)行和響應(yīng)。假設(shè)電梯有兩種運(yùn)行策略和,超時(shí)設(shè)定為秒,不考慮容量限制。保證如果電梯第一個人進(jìn)來后,秒后準(zhǔn)時(shí)運(yùn)送一次,不等待。 使用場景 某些場景下,一些計(jì)算量比較大的函數(shù),操作 DOM 函數(shù)等函數(shù)會被頻繁調(diào)用執(zhí)行,而且由于人的反應(yīng)有限實(shí)際不需要那么多計(jì)算,就會造成極大的性能浪費(fèi)。舉個例子當(dāng)...
摘要:起因面試被問到了節(jié)流和防抖動自己對這兩個的概念比較模糊都不知道回答了什么鬼從語文和英語學(xué)起首先先看字面意思節(jié)流的意思就是水龍頭關(guān)小點(diǎn)頻率不要那么高防抖動這根彈簧你不要來回蹦了我就要你最后停下來的沒有發(fā)生形變的那一刻舉個例子節(jié)流在改變窗口大小 起因 面試被問到了節(jié)流和防抖動, 自己對這兩個的概念比較模糊, 都不知道回答了什么鬼 從語文和英語學(xué)起 首先, 先看字面意思:節(jié)流(throttl...
閱讀 1081·2021-09-29 09:35
閱讀 4652·2021-09-22 15:24
閱讀 1458·2021-07-25 21:37
閱讀 2189·2019-08-30 14:17
閱讀 973·2019-08-30 13:56
閱讀 2418·2019-08-29 17:07
閱讀 1273·2019-08-29 12:44
閱讀 2711·2019-08-26 18:26