成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

剖析前端開(kāi)發(fā)中的防抖和節(jié)流

andong777 / 2410人閱讀

摘要:運(yùn)用防抖和節(jié)流可以有效降低代碼的執(zhí)行頻率,從而解決高頻率事件的頁(yè)面卡頓問(wèn)題。在階段布局,最終確定顯示的位置和大小。在函數(shù)中,首先定義了一個(gè)空的定時(shí)器變量,用來(lái)計(jì)算時(shí)間間隔。還有一點(diǎn)要注意,在中一定要清楚定時(shí)器,不然會(huì)影響的條件判斷。

啥是節(jié)流?

節(jié)流是保證在一段時(shí)間內(nèi),代碼只執(zhí)行了一次。這個(gè)一段時(shí)間內(nèi)指的是不管用戶操作了幾次,最終僅執(zhí)行一次。比如說(shuō)一個(gè)按鈕,用戶狂點(diǎn)按鈕,但是如果用節(jié)流技術(shù)的話,不管用戶點(diǎn)擊了幾次,最終某個(gè)時(shí)間段內(nèi)只執(zhí)行了一次代碼。這個(gè)時(shí)間段是可以自行設(shè)置,比如說(shuō)每一秒執(zhí)行一次。

啥是防抖?

防抖其實(shí)和節(jié)流有些類(lèi)似,畢竟它們的最終目的都是如出一轍。防抖是在一段時(shí)間結(jié)束之后,才觸發(fā)一次事件。如果一段時(shí)間內(nèi)未結(jié)束再次觸發(fā)了事件,那么就會(huì)重新計(jì)算這段時(shí)間。同樣的例子,還是用戶狂點(diǎn)按鈕。但是僅在用戶停止點(diǎn)擊按鈕后的一段時(shí)間之后才會(huì)執(zhí)行一次。如果用戶暫停點(diǎn)擊按鈕的時(shí)間不到一段時(shí)間內(nèi)又再次點(diǎn)擊按鈕,那么就會(huì)重新計(jì)算時(shí)間。這個(gè)時(shí)間同樣可以自行設(shè)置。

為啥要防抖或節(jié)流呢?

為了優(yōu)化高頻率事件,比如說(shuō)onscroll滾動(dòng) oninput搜索框聯(lián)想 resize窗口大小變化 onkeydown onkeyup...等等。這些高頻率事件很有可能導(dǎo)致頁(yè)面卡頓,影響用戶體驗(yàn)。運(yùn)用防抖和節(jié)流可以有效降低代碼的執(zhí)行頻率,從而解決高頻率事件的頁(yè)面卡頓問(wèn)題?;蛟S還有疑問(wèn),為啥高頻事件就會(huì)導(dǎo)致頁(yè)面卡頓呢?
這就要從頁(yè)面的展示過(guò)程說(shuō)起了。

頁(yè)面的展示過(guò)程

展示過(guò)程大致為以下順序:

Javascript -> Style -> Layout -> Paint -> Composite

首先,Javascript階段會(huì)往頁(yè)面中添加一些DOM或動(dòng)畫(huà),然后到Style階段確定每個(gè)DOM應(yīng)該用什么樣式規(guī)則。在Layout階段布局,最終確定DOM顯示的位置和大小。在Paint階段進(jìn)行DOM的繪制,它是在不同層上進(jìn)行繪制。注意,樣式變化是重繪,布局和位置變化是重排。重排一定導(dǎo)致重繪,重繪不一定導(dǎo)致重排。最后一個(gè)階段Composite進(jìn)行渲染層合并。(所以做一些動(dòng)畫(huà)效果盡量用CSS3的transform等屬性,因?yàn)樵搶傩允敲撾x文檔流,不用合并渲染層的。)由此可見(jiàn),如果觸發(fā)了很多高頻率的事件,就會(huì)導(dǎo)致頁(yè)面不停的確定位置和大小 ,不停的重排重繪并且合并渲染層。所以導(dǎo)致頁(yè)面卡頓也可以解釋了。

接下來(lái)會(huì)用例子來(lái)一步步實(shí)現(xiàn)節(jié)流和防抖的原理。

節(jié)流

首先 比如頁(yè)面上有個(gè)按鈕,用戶可以點(diǎn)擊該按鈕。該按鈕上綁定了一個(gè)點(diǎn)擊事件,用戶可以瘋狂點(diǎn)擊觸發(fā)該事件,肯定結(jié)果就是瘋狂觸發(fā)該事件。目標(biāo)是讓該按鈕不管用戶點(diǎn)擊的多快,最終該事件每秒僅執(zhí)行一次。




    
    
    
    throttle
    


    按鈕
    

可以看到,用戶瘋狂點(diǎn)擊了20次,那么該事件也理所當(dāng)然的執(zhí)行了20次,這顯然不是我們想要的。
基礎(chǔ)版:


    按鈕
    

為了盡可能的減少篇幅,把一些無(wú)用的代碼都刪除了。
定義一個(gè)throttle方法,該方法傳入了兩個(gè)參數(shù),一個(gè)是要執(zhí)行的事件,另一個(gè)是間隔時(shí)間。該throttle方法是一個(gè)閉包的寫(xiě)法,并且返回了一個(gè)函數(shù)。首先定義了上次的時(shí)間戳pre,pre默認(rèn)第一次為0。然后獲取到當(dāng)前時(shí)間,用當(dāng)前時(shí)間減去上次的時(shí)間戳也就是pre,如果這個(gè)差值大于了傳遞的時(shí)間間隔wait,也就表明可以執(zhí)行下一次的函數(shù)了。所以執(zhí)行方法并且傳遞this和參數(shù)。并把當(dāng)前時(shí)間賦給pre,以便做下一次節(jié)流的判斷。 看下效果:

可以看到,雖然瘋狂點(diǎn)擊按鈕,但是事件卻沒(méi)有瘋狂觸發(fā),保持了每一秒執(zhí)行一次的速度。也就達(dá)成了我們的目標(biāo)。
但是還有一個(gè)問(wèn)題就是,我最后點(diǎn)擊按鈕的那次也應(yīng)該延遲觸發(fā)最后一次的事件,但是結(jié)果并沒(méi)有。需要補(bǔ)上最后一次沒(méi)有觸發(fā)事件的問(wèn)題,接下來(lái)優(yōu)化它。
進(jìn)階版:


    按鈕
    

很明顯看到,進(jìn)階版多傳了一個(gè)參數(shù)對(duì)象,trailing:true。該參數(shù)用來(lái)表示是否執(zhí)行最后一次觸發(fā)的方法。
在函數(shù)中,首先定義了一個(gè)空的定時(shí)器變量timeout,用來(lái)計(jì)算時(shí)間間隔。其次多了一個(gè)else if的條件判斷,判斷如果時(shí)間間隔小于wait,就表示該方法要保留起來(lái)延遲去執(zhí)行。所以生成了一個(gè)定時(shí)器,延遲執(zhí)行l(wèi)ater函數(shù),later函數(shù)就是執(zhí)行該func函數(shù)。此處注意一點(diǎn),這個(gè)延遲時(shí)間的問(wèn)題。延遲時(shí)間不能是wait,必須是wait減去當(dāng)前時(shí)間和上次時(shí)間的時(shí)間獎(jiǎng)?lì)~。剩下的才是剩余時(shí)間延遲。還有一點(diǎn)要注意,在if中一定要清楚定時(shí)器,不然會(huì)影響else if的條件判斷。經(jīng)過(guò)測(cè)試,確實(shí)能在點(diǎn)擊的最后一次后,延遲不到一秒觸發(fā)了該事件。
剩下最后一個(gè)優(yōu)化點(diǎn),其實(shí)第一次點(diǎn)擊按鈕,也應(yīng)該延遲觸發(fā)事件。目前的版本是點(diǎn)擊按鈕的第一次就直接觸發(fā)該事件。優(yōu)化它:

最終版:


    按鈕
    

可以看到,傳遞一個(gè)新的參數(shù)對(duì)象leading為false。用來(lái)表示第一次也延遲執(zhí)行。那么問(wèn)題來(lái)了,怎樣才能第一次延遲執(zhí)行呢?實(shí)現(xiàn)其實(shí)很簡(jiǎn)單,進(jìn)階版已經(jīng)實(shí)現(xiàn)了else if延遲執(zhí)行,現(xiàn)只需讓第一次不走if,走else if就可實(shí)現(xiàn)第一次的延遲執(zhí)行??偣哺膭?dòng)僅兩處,第一處:判斷用戶是否傳遞了參數(shù)leading為false。如果傳遞了leading為false,則把當(dāng)前時(shí)間now賦給上次時(shí)間pre。為何這樣做呢? 目的就是為了第一步的時(shí)候也走else if。這么看。pre=now 那么if判斷條件就相當(dāng)與now-now。now-now=0,當(dāng)然不滿足if條件,即第一次走了else if。這還不算完,在else if中要校正pre時(shí)間。如果option.leading為false,那么pre就初始為0。pre為0的就會(huì)走if。只有走了if才會(huì)清空定時(shí)器,不然的話只會(huì)執(zhí)行一次便不會(huì)繼續(xù)往下執(zhí)行。因?yàn)閕f和else if的判斷條件都不滿足。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/117494.html

相關(guān)文章

  • 剖析前端開(kāi)發(fā)中的抖和節(jié)流

    摘要:運(yùn)用防抖和節(jié)流可以有效降低代碼的執(zhí)行頻率,從而解決高頻率事件的頁(yè)面卡頓問(wèn)題。在階段布局,最終確定顯示的位置和大小。在函數(shù)中,首先定義了一個(gè)空的定時(shí)器變量,用來(lái)計(jì)算時(shí)間間隔。還有一點(diǎn)要注意,在中一定要清楚定時(shí)器,不然會(huì)影響的條件判斷。 啥是節(jié)流? 節(jié)流是保證在一段時(shí)間內(nèi),代碼只執(zhí)行了一次。這個(gè)一段時(shí)間內(nèi)指的是不管用戶操作了幾次,最終僅執(zhí)行一次。比如說(shuō)一個(gè)按鈕,用戶狂點(diǎn)按鈕,但是如果用節(jié)流...

    LeexMuller 評(píng)論0 收藏0
  • 函數(shù)的抖和節(jié)流是個(gè)啥???

    摘要:函數(shù)防抖和節(jié)流,都是控制事件觸發(fā)頻率的方法。封裝一個(gè)函數(shù),讓持續(xù)觸發(fā)的事件監(jiān)聽(tīng)是我們封裝的這個(gè)函數(shù),將目標(biāo)函數(shù)作為回調(diào)傳進(jìn)去,等待一段時(shí)間過(guò)后執(zhí)行目標(biāo)函數(shù)第二點(diǎn)實(shí)現(xiàn)了,再看第一點(diǎn)持續(xù)觸發(fā)不執(zhí)行。 曾經(jīng)面試時(shí)候被問(wèn)到過(guò)這個(gè),年少的我一臉無(wú)知。。。 后來(lái)工作中遇到了一個(gè)場(chǎng)景:輸入名稱的同時(shí)去服務(wù)器校驗(yàn)名稱是否重復(fù),但發(fā)現(xiàn)之前的代碼竟然都沒(méi)做限制,輸入一次發(fā)一次請(qǐng)求。簡(jiǎn)直忍不了,就在項(xiàng)目的u...

    edagarli 評(píng)論0 收藏0
  • 小菊花課堂之JS的防抖節(jié)流

    摘要:文章來(lái)源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書(shū)示子聿》——古人學(xué)問(wèn)無(wú)遺力,少壯工夫老始成。紙上得來(lái)終覺(jué)淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩(shī)的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開(kāi)發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...

    leoperfect 評(píng)論0 收藏0
  • 小菊花課堂之JS的防抖節(jié)流

    摘要:文章來(lái)源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書(shū)示子聿》——古人學(xué)問(wèn)無(wú)遺力,少壯工夫老始成。紙上得來(lái)終覺(jué)淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩(shī)的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開(kāi)發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...

    Yangder 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

andong777

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<