成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

throttle與debounce的區(qū)別

Pluser / 1851人閱讀

摘要:自己嘗試一下年在的文章中第一次看到的實現(xiàn)方法。這三種實現(xiàn)方法內(nèi)部不同,但是接口幾乎一致。如你所見,我們使用了參數(shù),因為我們只對用戶停止改變?yōu)g覽器大小時最后一次事件感興趣。

前幾天看到一篇文章,我的公眾號里也分享了《一次發(fā)現(xiàn)underscore源碼bug的經(jīng)歷以及對學(xué)術(shù)界拿來主義的思考》具體文章詳見,微信公眾號:

文中講了大家對throttle和debounce存在誤解,同時提到了《高程3》中實現(xiàn)節(jié)流方法存在一些問題,為了更好的理解這兩個概念,搜了很多相關(guān)文章,詳見文章底部。

throttle與debounce是兩個類似的概念,目的都是隨著時間的推移控制執(zhí)行函數(shù)的次數(shù),但是有些細微的差別。

當(dāng)我們?yōu)镈OM事件關(guān)聯(lián)方法時,若我們有一個debounced和throttled函數(shù)將會很方便,為何?因為這樣我們可以在事件和執(zhí)行函數(shù)之間添加一層控制,注意我們并沒有去控制DOM事件觸發(fā)的次數(shù)。

例如,我們談一下scroll事件,看下面的例子:

See the Pen Scroll events counter by ghostcode (@ghostcode) on CodePen.

當(dāng)你在觸控板或者鼠標滾動時,每次最少會達到30次,在手機上更多??墒悄愕臐L動事件處理函數(shù)對這個頻率是否應(yīng)付的過來?

在2011年,Twitter網(wǎng)站曾爆出一個問題:當(dāng)你在主頁往下滾動時,頁面會變得緩慢以致沒有響應(yīng)。John Resig發(fā)表了一篇文章《 a blog post about the problem》指出直接在scroll事件上面綁定高消耗的事件是一個多么愚蠢的想法。

在那個時候John建議使用一個獨立于scroll事件且每250ms執(zhí)行的輪詢方法。這樣的話處理方法就不會耦合于事件。通過這個簡單的技術(shù),我們可以提高用戶體驗。

現(xiàn)在有一些更先進的事件處理方法,讓我來給你介紹:__Debounce,Throttle和requestAnimationFrame__,同時會介紹一些適用的場景。

Debounce

Debounce技術(shù)使我們可以將一個連續(xù)的調(diào)用歸為一個。

想象你在電梯的場景,當(dāng)電梯門開始要關(guān)閉的時候,突然一個人進來,此時電梯并不會關(guān)閉并且也不會執(zhí)行改變樓層的方法,如果還有人進來同樣的事情會發(fā)生:電梯延遲執(zhí)行它的方法(改變樓層),優(yōu)化了它的資源。

自己嘗試一下,在按鈕上點擊或者移動鼠標:

See the Pen Debounce. Trailing by ghostcode (@ghostcode) on CodePen.

你可以看到快速連續(xù)的事件是如何通過一個debounce事件來表示的。

Leading edge (or "immediate")

你可以發(fā)現(xiàn)事件結(jié)束的時候,debounce的事件并沒有立即執(zhí)行而是等待了一些時間才觸發(fā)。為何不立即觸發(fā),就像開始沒有使用debounce事件處理?直到在連續(xù)執(zhí)行的事件中有一個暫停,才會再次觸發(fā)。

你可以通過一個__leading__的參數(shù)做到:

在underscore.js中,這個參數(shù)叫immediate。

自己嘗試一下:

See the Pen Debounce. Leading by ghostcode (@ghostcode) on CodePen.

Debounce Implementations

2009年在John Hann的文章中第一次看到debounce的實現(xiàn)方法。

在那之后不久,Ben Alman寫了一個jQuery插件(現(xiàn)在不在維護),一年以后Jeremy Ashkenas把此方法添加到underscore.js中,不久又被添加到lodash中。

See the Pen debounce-click by ghostcode (@ghostcode) on CodePen.

這三種實現(xiàn)方法內(nèi)部不同,但是接口幾乎一致。

有段時間underscore采用了Lodash的實現(xiàn)方法,但是在我發(fā)現(xiàn)了一個bug之后,自此兩個庫的實現(xiàn)開始分道揚鑣。

Lodash在_.debounce和_.throttle中添加了許多特性。immediate標示替代了leading和trailing。你可以二選一或者都選,默認情況下,只有trailing是開啟的。

Debounce Examples

當(dāng)改變?yōu)g覽器窗口時,resize事件會觸發(fā)多次。

See the Pen Debounce Resize Event Example by ghostcode (@ghostcode) on CodePen.

如你所見,我們使用了__trailing__參數(shù),因為我們只對用戶停止改變?yōu)g覽器大小時最后一次事件感興趣。

AutoComplete中的Ajax請求使用的keypress

當(dāng)用戶仍舊在輸入的時候,為何每隔50ms發(fā)送Ajax請求?__ _.debounce __可以幫助我們避免額外的工作,只在用戶停止輸入的時候發(fā)送請求。

See the Pen Debouncing keystrokes Example by ghostcode (@ghostcode) on CodePen.

另一個使用場景是在進行input校驗的時候,“你的密碼太短”等類似的信息。

如何使用debounce和throttle以及常見的陷阱?

可以自己實現(xiàn)這兩個方法或者隨便復(fù)制別人blog中的實現(xiàn)方法,我的建議是直接使用underscore和lodash中的方法。如果你只需要這兩個方法,可以定制輸出lodash方法:

npm i -g lodash-cli
lodash-cli include=debounce,throttle

一個常見的陷阱:

// WRONG
$(window).on("scroll", function() {
   _.debounce(doSomething, 300); 
});

// RIGHT
$(window).on("scroll", _.debounce(doSomething, 200));

debounce方法賦值給一個變量之后允許我們調(diào)用一個私有方法:__debounced_version.cancel()__:

var debounced_version = _.debounce(doSomething, 200);
$(window).on("scroll", debounced_version);

// If you need it
debounced_version.cancel();

Throttle

使用__ _.throttle __,我們不允許方法在每Xms間執(zhí)行超過一次。

和debounce的主要區(qū)別是throttle保證方法每Xms有規(guī)律的執(zhí)行。

Throttling Examples

一個相當(dāng)常見的例子,用戶在你無限滾動的頁面上向下拖動,你需要判斷現(xiàn)在距離頁面底部多少。如果用戶快接近底部時,我們應(yīng)該發(fā)送請求來加載更多內(nèi)容到頁面。

在此__ _.debounce 沒有用,因為它只會在用戶停止?jié)L動時觸發(fā),但我們需要用戶快到達底部時去請求。通過 _.throttle __我們可以不間斷的監(jiān)測距離底部多遠。

See the Pen Infinite scrolling throttled by ghostcode (@ghostcode) on CodePen.

requestAnimationFrame (rAF)

requestAnimationFrame是另一個頻率限制的方法。

它可以通過__ _.throttle(dosomething, 16)__實現(xiàn),但為了更加精準瀏覽器提供了內(nèi)置API。

我們可以使用rAF API作為throttle方法的替代,考慮一下利弊:

利:

目標60fps(16ms每貞),但是內(nèi)部使用最優(yōu)的時間間隔來渲染

使用簡單并且是標準API,以后不會變動,不需要維護

弊:

rAF的開始或者取消需要我們自己處理,不像.debounce和.throttle內(nèi)部實現(xiàn)

瀏覽器Tag沒有激活,它就不會執(zhí)行

即使多數(shù)現(xiàn)代瀏覽器支持,但是IE9,Opera Mini以及老版本Android依舊不支持。A polyfill到現(xiàn)在依舊需要

rAF在node.js中不支持

根據(jù)經(jīng)驗,我建議在JS執(zhí)行"painting"或"animating"中直接操作屬性和重新計算元素位置時使用rAF。

發(fā)送Ajax請求或者是否添加/刪除class(觸發(fā)一個CSS動畫)時,我會考慮debounce和throttle,此時你可以降低執(zhí)行頻率(200ms而不是16ms)。

rAF的例子

在Paul Lewis的文章激發(fā)下,我只在scroll事件中提供例子。

我一步步的調(diào)throttle到16ms,希望給一個類似的體驗,但是rAF在復(fù)雜場景下或許會提供更好的結(jié)果。

See the Pen Scroll comparison requestAnimationFrame vs throttle by ghostcode (@ghostcode) on CodePen.

一個更好的例子我是在headroom.js中看到的,這里通過一個對象封裝,進行了邏輯解藕。

總結(jié):
使用debounce,throttle和requestAnimationFrame優(yōu)化你的事件處理函數(shù)。每一個方法有一些細微的差別,三個都很有用而且互相彌補。

__debounce:__把突然涌進的事件(鍵盤事件)歸位一個

__throttle:__保證持續(xù)執(zhí)行方法分隔為每Xms執(zhí)行一次。就像每200ms監(jiān)測滾動位置來觸發(fā)css動畫。

__requestAnimationFrame:__throttle的替代方案,當(dāng)你的方法需要重新計算和渲染元素同時你需要更平滑的變動或動畫。注意:IE9- 不支持。

https://blog.coding.net/blog/...

https://css-tricks.com/the-di...

http://stackoverflow.com/ques...

http://demo.nimius.net/deboun...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79156.html

相關(guān)文章

  • JS throttledebounce區(qū)別

    摘要:可以看下面的栗子這個圖中圖中每個小格大約,右邊有原生事件與節(jié)流去抖插件的與事件。即如果有連續(xù)不斷的觸發(fā),每執(zhí)行一次,用在每隔一定間隔執(zhí)行回調(diào)的場景。執(zhí)行啦打印執(zhí)行啦打印執(zhí)行啦節(jié)流按照上面的說明,節(jié)流就是連續(xù)多次內(nèi)的操作按照指定的間隔來執(zhí)行。 一般在項目中我們會對input、scroll、resize等事件進行節(jié)流控制,防止事件過多觸發(fā),減少資源消耗;在vue的官網(wǎng)的例子中就有關(guān)于lod...

    wawor4827 評論0 收藏0
  • Debounce vs Throttle

    摘要:那么還有最后一個問題,那我之前設(shè)置的定時器怎么辦呢定時器執(zhí)行的是這個函數(shù),而這個函數(shù)又會通過進行一次判斷。 我們在處理事件的時候,有些事件由于觸發(fā)太頻繁,而每次事件都處理的話,會消耗太多資源,導(dǎo)致瀏覽器崩潰。最常見的是我們在移動端實現(xiàn)無限加載的時候,移動端本來滾動就不是很靈敏,如果每次滾動都處理的話,界面就直接卡死了。 因此,我們通常會選擇,不立即處理事件,而是在觸發(fā)一定次數(shù)或一定時間...

    xcold 評論0 收藏0
  • 一次發(fā)現(xiàn)underscore源碼bug經(jīng)歷以及對學(xué)術(shù)界拿來主義思考

    摘要:事情是如何發(fā)生的最近干了件事情,發(fā)現(xiàn)了源碼的一個。樓主找到的關(guān)于和區(qū)別的資料如下關(guān)于拿來主義為什么這么多文章里會出現(xiàn)澤卡斯的錯誤代碼樓主想到了一個詞,叫做拿來主義。的文章,就深刻抨擊了拿來主義這一現(xiàn)象。 事情是如何發(fā)生的 最近干了件事情,發(fā)現(xiàn)了 underscore 源碼的一個 bug。這件事本身并沒有什么可說的,但是過程值得我們深思,記錄如下,各位看官仁者見仁智者見智。 平時有瀏覽別...

    Lionad-Morotar 評論0 收藏0
  • debouncing throttling

    摘要:一個使用場景某些瀏覽器事件可能會在短時間內(nèi)高頻觸發(fā),比如整窗口大小或滾動頁面。這會導(dǎo)致非常嚴重的性能問題。實現(xiàn)與類似,接收兩個參數(shù),一個是需要截流的函數(shù),另一個是函數(shù)執(zhí)行間隔閾值。 一個使用場景:某些瀏覽器事件可能會在短時間內(nèi)高頻觸發(fā),比如:整窗口大小或滾動頁面。如果給窗口滾動事件添加一個事件監(jiān)聽器,然后用戶不停地快速滾動頁面,那你的事件可能在短短數(shù)秒之內(nèi)被觸發(fā)數(shù)千次。這會導(dǎo)致非常嚴重...

    zzir 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<