亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

你應(yīng)該知道的requestIdleCallback

SunZhaopeng / 1498人閱讀

摘要:因?yàn)榛卣{(diào)的執(zhí)行的前提條件是當(dāng)前瀏覽器處于空閑狀態(tài)。除了不推薦修改操作外,的操作也不建議放在里面,因?yàn)榈幕卣{(diào)會(huì)在的回調(diào)執(zhí)行完成后立刻執(zhí)行,會(huì)拉長(zhǎng)當(dāng)前幀的耗時(shí),所以不推薦。推薦放在里面的應(yīng)該是小塊的并且可預(yù)測(cè)時(shí)間的任務(wù)。

我們都知道React 16實(shí)現(xiàn)了新的調(diào)度策略(Fiber), 新的調(diào)度策略提到的異步、可中斷,其實(shí)就是基于瀏覽器的 requestIdleCallback和requestAnimationFrame兩個(gè)API。所以這里我們有必要了解一下這兩個(gè)API,關(guān)于Fiber部分后面會(huì)單開幾篇講。

什么是requestIdleCallback?

當(dāng)關(guān)注用戶體驗(yàn),不希望因?yàn)橐恍┎恢匾娜蝿?wù)(如統(tǒng)計(jì)上報(bào))導(dǎo)致用戶感覺到卡頓的話,就應(yīng)該考慮使用requestIdleCallback。因?yàn)閞equestIdleCallback回調(diào)的執(zhí)行的前提條件是當(dāng)前瀏覽器處于空閑狀態(tài)。

requestIdleCallback will schedule work when there is free time at the end of a frame, or when the user is inactive.

requestIdleCallback用法示例

    requestIdelCallback(myNonEssentialWork);
    
    
    function myNonEssentialWork (deadline) {
    
      // deadline.timeRemaining()可以獲取到當(dāng)前幀剩余時(shí)間
      while (deadline.timeRemaining() > 0 && tasks.length > 0) {
        doWorkIfNeeded();
      }
      if (tasks.length > 0){
        requestIdleCallback(myNonEssentialWork);
      }
    }
requestIdleCallback和requestAnimationFrame有什么區(qū)別?

requestAnimationFrame的回調(diào)會(huì)在每一幀確定執(zhí)行,屬于高優(yōu)先級(jí)任務(wù),而requestIdleCallback的回調(diào)則不一定,屬于低優(yōu)先級(jí)任務(wù)。
我們所看到的網(wǎng)頁,都是瀏覽器一幀一幀繪制出來的,通常認(rèn)為FPS為60的時(shí)候是比較流暢的,而FPS為個(gè)位數(shù)的時(shí)候就屬于用戶可以感知到的卡頓了,那么在一幀里面瀏覽器都要做哪些事情呢,如下所示:

圖中一幀包含了用戶的交互、js的執(zhí)行、以及requestAnimationFrame的調(diào)用,布局計(jì)算以及頁面的重繪等工作。
假如某一幀里面要執(zhí)行的任務(wù)不多,在不到16ms(1000/60)的時(shí)間內(nèi)就完成了上述任務(wù)的話,那么這一幀就會(huì)有一定的空閑時(shí)間,這段時(shí)間就恰好可以用來執(zhí)行requestIdleCallback的回調(diào),如下圖所示:

由于requestIdleCallback利用的是幀的空閑時(shí)間,所以就有可能出現(xiàn)瀏覽器一直處于繁忙狀態(tài),導(dǎo)致回調(diào)一直無法執(zhí)行,這其實(shí)也并不是我們期望的結(jié)果(如上報(bào)丟失),那么這種情況我們就需要在調(diào)用requestIdleCallback的時(shí)候傳入第二個(gè)配置參數(shù)timeout了?

requestIdleCallback(myNonEssentialWork, { timeout: 2000 });

function myNonEssentialWork (deadline) {
  // 當(dāng)回調(diào)函數(shù)是由于超時(shí)才得以執(zhí)行的話,deadline.didTimeout為true
  while ((deadline.timeRemaining() > 0 || deadline.didTimeout) &&
         tasks.length > 0) {
       doWorkIfNeeded();
    }
  if (tasks.length > 0) {
    requestIdleCallback(myNonEssentialWork);
  }
}

如果是因?yàn)閠imeout回調(diào)才得以執(zhí)行的話,其實(shí)用戶就有可能會(huì)感覺到卡頓了,因?yàn)橐粠膱?zhí)行時(shí)間必然已經(jīng)超過16ms了

requestIdleCallback里面可以執(zhí)行DOM修改操作嗎?

強(qiáng)烈建議不要,從上面一幀的構(gòu)成里面可以看到,requestIdleCallback回調(diào)的執(zhí)行說明前面的工作(包括樣式變更以及布局計(jì)算)都已完成。如果我們?cè)赾allback里面做DOM修改的話,之前所做的布局計(jì)算都會(huì)失效,而且如果下一幀里有獲取布局(如getBoundingClientRect、clientWidth)等操作的話,瀏覽器就不得不執(zhí)行強(qiáng)制重排工作,這會(huì)極大的影響性能,另外由于修改dom操作的時(shí)間是不可預(yù)測(cè)的,因此很容易超出當(dāng)前幀空閑時(shí)間的閾值,故而不推薦這么做。推薦的做法是在requestAnimationFrame里面做dom的修改,可以在requestIdleCallback里面構(gòu)建Document Fragment,然后在下一幀的requestAnimationFrame里面應(yīng)用Fragment。

除了不推薦DOM修改操作外,Promise的resolve(reject)操作也不建議放在里面,因?yàn)镻romise的回調(diào)會(huì)在idle的回調(diào)執(zhí)行完成后立刻執(zhí)行,會(huì)拉長(zhǎng)當(dāng)前幀的耗時(shí),所以不推薦。

推薦放在requestIdleCallback里面的應(yīng)該是小塊的(microTask)并且可預(yù)測(cè)時(shí)間的任務(wù)。關(guān)于microTask推薦看這里

requestIdleCallback的兼容情況


推薦使用npm包request-idle-callback

參考資料

https://developers.google.com...
https://medium.com/@paul_iris...
https://juejin.im/entry/59082...
https://insights.thoughtworks...

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/94379.html

相關(guān)文章

  • 「譯」代碼優(yōu)化策略 — Idle Until Urgent

    摘要:我將這個(gè)策略稱之為閑置直到緊急。請(qǐng)注意,在腳本執(zhí)行時(shí),它作為單個(gè)任務(wù)需要毫秒才能運(yùn)行完成。很明顯,解決方案是將這些代碼分解為多個(gè)任務(wù)。原因如下推遲組件初始化僅在組件尚未渲染時(shí)才有用。這稱為輸入優(yōu)先級(jí)。 showImg(https://img.alicdn.com/tfs/TB1u.rsepzqK1RjSZFzXXXjrpXa-1919-913.png); Idle Until Urge...

    Ashin 評(píng)論0 收藏0
  • Deep In React之淺談 React Fiber 架構(gòu)(一)

    摘要:在上面我們已經(jīng)知道瀏覽器是一幀一幀執(zhí)行的,在兩個(gè)執(zhí)行幀之間,主線程通常會(huì)有一小段空閑時(shí)間,可以在這個(gè)空閑期調(diào)用空閑期回調(diào),執(zhí)行一些任務(wù)。另外由于這些堆棧是可以自己控制的,所以可以加入并發(fā)或者錯(cuò)誤邊界等功能。 文章首發(fā)于個(gè)人博客 前言 2016 年都已經(jīng)透露出來的概念,這都 9102 年了,我才開始寫 Fiber 的文章,表示慚愧呀。不過現(xiàn)在好的是關(guān)于 Fiber 的資料已經(jīng)很豐富了,...

    Jiavan 評(píng)論0 收藏0
  • 「React 16」為 Luy 實(shí)現(xiàn) React Fiber 架構(gòu)

    摘要:開始寫代碼構(gòu)造函數(shù)講了那么多的理論,大家一定是暈了,但是沒辦法,架構(gòu)已經(jīng)比之前的簡(jiǎn)單要復(fù)雜太多了,因此不可能指望一次性把的內(nèi)容全部理解,需要反復(fù)多看。 前言 Facebook 的研發(fā)能力真是驚人, Fiber 架構(gòu)給 React 帶來了新視野的同時(shí),將調(diào)度一詞介紹給了前端,然而這個(gè)架構(gòu)實(shí)在不好懂,比起以前的 Vdom 樹,新的 Fiber 樹就麻煩太多。 可以說,React 16 和 ...

    DevWiki 評(píng)論0 收藏0
  • React Fiber 架構(gòu)理解

    摘要:架構(gòu)理解引用原文是核心算法正在進(jìn)行的重新實(shí)現(xiàn)。構(gòu)建的過程就是的過程,通過來調(diào)度執(zhí)行一組任務(wù),每完成一個(gè)任務(wù)后回來看看有沒有插隊(duì)的更緊急的,把時(shí)間控制權(quán)交還給主線程,直到下一次回調(diào)再繼續(xù)構(gòu)建。 React Fiber 架構(gòu)理解 引用原文:React Fiber ArchitectureReact Fiber is an ongoing reimplementation of Reacts...

    Berwin 評(píng)論0 收藏0
  • 2017前端技術(shù)預(yù)覽(未完結(jié),最后更新于1月13日)

    摘要:圖離線情況下發(fā)送微信消息,等網(wǎng)絡(luò)正常后微信會(huì)繼續(xù)處理我們的消息。無論是在微信中還是手機(jī)短信,在沒有信號(hào)時(shí)都不影響我們編輯發(fā)送短信,等網(wǎng)絡(luò)恢復(fù)時(shí)會(huì)自動(dòng)幫我們把之前編輯好的信息順利遞送出去。 (刪掉了第一小段,因?yàn)楹蛢?nèi)容關(guān)系不大。。) 本來這該是個(gè)技術(shù)分享會(huì)的內(nèi)容,參加完 Google Developer Day(GDD) 后想做個(gè) AI Demo 來分享,奈何技術(shù)實(shí)力不夠,害怕把大家?guī)нM(jìn)...

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

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

0條評(píng)論

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