摘要:但是,我在測(cè)試中,智能手機(jī)中的慢速滾動(dòng)可能會(huì)觸發(fā)每秒多達(dá)個(gè)事件。把電梯完成一次運(yùn)送,類比為一次函數(shù)的執(zhí)行和響應(yīng)。假設(shè)電梯有兩種運(yùn)行策略和,超時(shí)設(shè)定為秒,不考慮容量限制。保證如果電梯第一個(gè)人進(jìn)來(lái)后,秒后準(zhǔn)時(shí)運(yùn)送一次,不等待。
使用場(chǎng)景
某些場(chǎng)景下,一些計(jì)算量比較大的函數(shù),操作 DOM 函數(shù)等函數(shù)會(huì)被頻繁調(diào)用執(zhí)行,而且由于人的反應(yīng)有限實(shí)際不需要那么多計(jì)算,就會(huì)造成極大的性能浪費(fèi)。
舉個(gè)例子
當(dāng)使用鼠標(biāo)滾輪時(shí)可以輕松觸發(fā)每秒30個(gè)事件。但是,我在測(cè)試中,智能手機(jī)中的慢速滾動(dòng)可能會(huì)觸發(fā)每秒多達(dá)100個(gè)事件。你的滾動(dòng)處理程序是否真的需要這個(gè)執(zhí)行速度?
下面我列舉一些場(chǎng)景
window對(duì)象的resize、scroll事件,如處理圖片懶加載
拖拽時(shí)的mousemove事件
鍵盤 keyup 事件
...
原理那么throttle 和 debounce 函數(shù)是怎樣做的呢?
這里引用經(jīng)典的舉例
想象每天上班大廈底下的電梯。把電梯完成一次運(yùn)送,類比為一次函數(shù)的執(zhí)行和響應(yīng)。假設(shè)電梯有兩種運(yùn)行策略 throttle 和 debounce ,超時(shí)設(shè)定為15秒,不考慮容量限制。
1.throttle 策略的電梯。保證如果電梯第一個(gè)人進(jìn)來(lái)后,15秒后準(zhǔn)時(shí)運(yùn)送一次,不等待。如果沒(méi)有人,則待機(jī)。
2.debounce 策略的電梯。如果電梯里有人進(jìn)來(lái),等待15秒。如果又人進(jìn)來(lái),15秒等待重新計(jì)時(shí),直到15秒超時(shí),開始運(yùn)送。
用我的一句話說(shuō)是,throttle 在一段時(shí)間內(nèi)最多執(zhí)行一次,而 debounce 是在接下來(lái)一段時(shí)間內(nèi)沒(méi)有再次調(diào)用,則執(zhí)行。
實(shí)現(xiàn)由于說(shuō)了是簡(jiǎn)單實(shí)現(xiàn),那么就把最核心的部分拿出來(lái)
debouncefunction debounce (cb, delay) { var timer = null; return function () { clearTimeout(timer); timer = setTimeout(cb, delay); } }throttle
function throttle (cb, delay) { var lastTime = Date.now(); return function () { var nowTime = Date.now(); if (nowTime - lastTime > delay) { cb(); lastTime = nowTime; } } }
可以看下效果
查看鏈接
知道原理之后,想要使用,現(xiàn)在很多庫(kù)都有這個(gè)功能
jquery 插件 jQuery throttle / debounce
Underscore 庫(kù) _.throttle 和 _.debounce
lodash 庫(kù) _.debounce 和 _.throttle
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/95700.html
摘要:淺談以及的原理和實(shí)現(xiàn)背景日常開發(fā)中我們經(jīng)常會(huì)遇到一些需要節(jié)流調(diào)用或者壓縮調(diào)用次數(shù)的情況例如之前我在完成一個(gè)需求的時(shí)候就遇到了因?yàn)楹蠖瞬l(fā)問(wèn)題導(dǎo)致收到多條信息從而導(dǎo)致函數(shù)被重復(fù)調(diào)用的情況當(dāng)時(shí)的做法是通過(guò)對(duì)函數(shù)的調(diào)用進(jìn)行注冊(cè)遇到多次調(diào)用的時(shí)候清 淺談throttle以及debounce的原理和實(shí)現(xiàn) 背景 日常開發(fā)中,我們經(jīng)常會(huì)遇到一些需要節(jié)流調(diào)用,或者壓縮調(diào)用次數(shù)的情況,例如之前我在完成...
摘要:舉例舉例通過(guò)拖拽瀏覽器窗口,可以觸發(fā)很多次事件。不支持,所以不能在服務(wù)端用于文件系統(tǒng)事件??偨Y(jié)將一系列迅速觸發(fā)的事件例如敲擊鍵盤合并成一個(gè)單獨(dú)的事件。確保一個(gè)持續(xù)的操作流以每毫秒執(zhí)行一次的速度執(zhí)行。 Debounce 和 Throttle 是兩個(gè)很相似但是又不同的技術(shù),都可以控制一個(gè)函數(shù)在一段時(shí)間內(nèi)執(zhí)行的次數(shù)。 當(dāng)我們?cè)诓僮?DOM 事件的時(shí)候,為函數(shù)添加 debounce 或者 th...
摘要:那么還有最后一個(gè)問(wèn)題,那我之前設(shè)置的定時(shí)器怎么辦呢定時(shí)器執(zhí)行的是這個(gè)函數(shù),而這個(gè)函數(shù)又會(huì)通過(guò)進(jìn)行一次判斷。 我們?cè)谔幚硎录臅r(shí)候,有些事件由于觸發(fā)太頻繁,而每次事件都處理的話,會(huì)消耗太多資源,導(dǎo)致瀏覽器崩潰。最常見(jiàn)的是我們?cè)谝苿?dòng)端實(shí)現(xiàn)無(wú)限加載的時(shí)候,移動(dòng)端本來(lái)滾動(dòng)就不是很靈敏,如果每次滾動(dòng)都處理的話,界面就直接卡死了。 因此,我們通常會(huì)選擇,不立即處理事件,而是在觸發(fā)一定次數(shù)或一定時(shí)間...
摘要:當(dāng)函數(shù)被再次觸發(fā)時(shí),清除已設(shè)置的定時(shí)器,重新設(shè)置定時(shí)器。函數(shù)設(shè)置定時(shí)器,并根據(jù)傳參配置決定是否在等待開始時(shí)執(zhí)行函數(shù)。函數(shù)取消定時(shí)器,并重置內(nèi)部參數(shù)。 throttle函數(shù)與debounce函數(shù) 有時(shí)候,我們會(huì)對(duì)一些觸發(fā)頻率較高的事件進(jìn)行監(jiān)聽,如果在回調(diào)里執(zhí)行高性能消耗的操作,反復(fù)觸發(fā)時(shí)會(huì)使得性能消耗提高,瀏覽器卡頓,用戶使用體驗(yàn)差。或者我們需要對(duì)觸發(fā)的事件延遲執(zhí)行回調(diào),此時(shí)可以借助th...
摘要:自己嘗試一下年在的文章中第一次看到的實(shí)現(xiàn)方法。這三種實(shí)現(xiàn)方法內(nèi)部不同,但是接口幾乎一致。如你所見(jiàn),我們使用了參數(shù),因?yàn)槲覀冎粚?duì)用戶停止改變?yōu)g覽器大小時(shí)最后一次事件感興趣。 前幾天看到一篇文章,我的公眾號(hào)里也分享了《一次發(fā)現(xiàn)underscore源碼bug的經(jīng)歷以及對(duì)學(xué)術(shù)界拿來(lái)主義的思考》具體文章詳見(jiàn),微信公眾號(hào):showImg(https://segmentfault.com/img/b...
閱讀 1451·2021-11-22 13:54
閱讀 4369·2021-09-22 15:56
閱讀 1825·2021-09-03 10:30
閱讀 1324·2021-09-03 10:30
閱讀 2091·2019-08-30 15:55
閱讀 1858·2019-08-30 14:13
閱讀 2064·2019-08-29 15:19
閱讀 2368·2019-08-28 18:13