<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你不知道的頁面生命周期API

          共 3093字,需瀏覽 7分鐘

           ·

          2021-01-20 20:56

          關(guān)于本 譯者:@飄飄 作者:@Viduni Wickramarachchi 原文:https://blog.bitsrc.io/page-lifecycle-api-a-browser-api-every-frontend-developer-should-know-b1c74948bd74

          前言

          曾經(jīng)碰到過這么個(gè)場景,統(tǒng)計(jì)用戶在該游戲停留時(shí)間。文章由@飄飄翻譯。

          每個(gè)前端開發(fā)人員都應(yīng)該知道的瀏覽器API

          作為用戶,我們在瀏覽網(wǎng)頁時(shí)總喜歡一心多用。因此,打開多個(gè)瀏覽器標(biāo)簽頁是很常見的,因?yàn)檫@有助于并行完成事情。但同時(shí),每一個(gè)標(biāo)簽頁都會(huì)消耗系統(tǒng)資源,比如內(nèi)存和CPU。

          由于不可能限制用戶打開新的瀏覽器標(biāo)簽頁并將其留下,因此瀏覽器采取了一些措施,以在瀏覽器標(biāo)簽頁不活動(dòng)時(shí)重新分配資源。

          現(xiàn)在的現(xiàn)代瀏覽器有時(shí)會(huì)在系統(tǒng)資源緊張的情況下暫停頁面或完全丟棄頁面--菲利普-沃爾頓。

          那么你可能會(huì)有疑問,既然瀏覽器已經(jīng)處理好了,我們?yōu)槭裁催€要擔(dān)心這個(gè)問題呢?

          并非完全如此,瀏覽器會(huì)照顧到一切。此外,這些瀏覽器的干預(yù)會(huì)直接影響到JavaScript的執(zhí)行。好消息是,幾乎所有的現(xiàn)代瀏覽器都通過頁面生命周期API將這些干預(yù)作為事件暴露出來。

          頁面生命周期API

          顧名思義,頁面生命周期API將網(wǎng)頁生命周期的鉤子暴露給JavaScript。然而,這并不是一個(gè)全新的概念。頁面可見性API存在了有一段時(shí)間,向JavaScript揭示了一些頁面可見性事件。

          然而,如果你碰巧在這兩者之間做出選擇,值得一提的是Page Visibility API的一些限制。

          • 它只提供網(wǎng)頁的可見和隱藏狀態(tài)。

          • 它不能捕獲被操作系統(tǒng)丟棄的頁面(Android、IOS和最新的Windows系統(tǒng)可以終止后臺進(jìn)程以保存系統(tǒng)資源)。

          我們來看看頁面生命周期API所暴露的頁面生命周期狀態(tài)。

          頁面生命周期API狀態(tài)

          在API中介紹了6種狀態(tài),其中有兩種狀態(tài)與我們頗為相關(guān)。其中,有兩個(gè)狀態(tài)與我們相當(dāng)相關(guān)。

          FROZEN--CPU暫停的生命周期狀態(tài)(隱藏的網(wǎng)頁會(huì)被凍結(jié)以節(jié)約資源)。

          如果一個(gè)網(wǎng)頁被隱藏了很久,而用戶沒有關(guān)閉網(wǎng)頁,瀏覽器會(huì)將其凍結(jié),并將網(wǎng)頁移動(dòng)到這個(gè)狀態(tài)。但是,正在運(yùn)行的任務(wù)會(huì)繼續(xù)進(jìn)行,直到完成。但定時(shí)器、回調(diào)函數(shù)執(zhí)行和DOM操作將被停止以釋放CPU。

          Chrome瀏覽器資源消耗

          當(dāng)我查看電腦上Chrome瀏覽器的資源消耗時(shí),我觀察到兩個(gè)活動(dòng)標(biāo)簽頁分別消耗了14.7%和11%的CPU,而凍結(jié)的標(biāo)簽頁消耗了近0%的CPU。

          DISCARDED - 為了節(jié)省資源,將凍結(jié)狀態(tài)移動(dòng)到Discarded狀態(tài)。

          假設(shè)一個(gè)網(wǎng)頁長時(shí)間處于凍結(jié)狀態(tài),在這種情況下,瀏覽器會(huì)自動(dòng)將網(wǎng)頁卸載到丟棄狀態(tài),以節(jié)省資源。在這種情況下,瀏覽器會(huì)自動(dòng)將頁面卸載到丟棄狀態(tài),釋放一些內(nèi)存。而如果用戶再次訪問被丟棄的頁面,瀏覽器會(huì)重新加載頁面,回到活動(dòng)狀態(tài)。

          值得注意的是,用戶一般會(huì)在資源受限的設(shè)備中體驗(yàn)到丟棄狀態(tài)。

          除了以上兩種狀態(tài)外,API中還引入了其他四種狀態(tài),分別是:。

          • ACTIVE - 頁面可見并有輸入焦點(diǎn)。

          • PASSIVE - 頁面可見,但沒有輸入焦點(diǎn)。

          • HIDDEN - 頁面不可見(也沒有凍結(jié))。

          • TERMINATED - 頁面被卸載并從內(nèi)存中清除。

          你可以通過看下圖找到生命周期狀態(tài)和過渡的細(xì)節(jié)。

          頁面生命周期API狀態(tài)和過渡

          如何應(yīng)對生命周期狀態(tài)?

          現(xiàn)在我們已經(jīng)了解了頁面生命周期API,讓我們看看如何響應(yīng)每個(gè)事件。

          這里最重要的是確定當(dāng)應(yīng)用程序達(dá)到每個(gè)狀態(tài)時(shí),哪些需要保留,哪些需要停止。

          • ACTIVE狀態(tài)--由于用戶在頁面上是完全活躍的,所以你的網(wǎng)頁應(yīng)該完全響應(yīng)用戶的輸入。任何UI阻塞任務(wù)都應(yīng)該被去掉優(yōu)先級,比如同步和阻塞網(wǎng)絡(luò)請求。

          • PASSIVE狀態(tài)--即使用戶在這個(gè)階段沒有與頁面進(jìn)行交互,他們?nèi)匀豢梢钥吹剿R虼四愕木W(wǎng)頁應(yīng)該流暢地運(yùn)行所有的UI更新和動(dòng)畫。

          • HIDDEN狀態(tài) - 隱藏狀態(tài)應(yīng)該被視為用戶在網(wǎng)頁上的會(huì)話的結(jié)束。你可以在此時(shí)堅(jiān)持未保存的應(yīng)用狀態(tài),并停止任何用戶不需要在后臺運(yùn)行的UI更新或任務(wù)。

          • Frozen狀態(tài) - 任何可能影響其他標(biāo)簽頁的定時(shí)器和連接都應(yīng)該在這個(gè)階段終止。例如,你應(yīng)該關(guān)閉所有打開的IndexedDB連接,任何打開的Web Socket連接,釋放任何被持有的Web鎖,等等。

          • Terminated狀態(tài) - 由于會(huì)話結(jié)束邏輯是在隱藏狀態(tài)下處理的,所以一般不需要任何操作。

          • Discarded狀態(tài) - 這個(gè)狀態(tài)是應(yīng)用程序無法觀察到的。因此,任何可能的丟棄的準(zhǔn)備工作都應(yīng)該在隱藏或凍結(jié)狀態(tài)下進(jìn)行。然而,你可以在頁面加載時(shí)通過檢查document.wasDiscarded來對頁面的任何恢復(fù)做出反應(yīng)。

          好了,現(xiàn)在我們知道在每個(gè)狀態(tài)下要做什么了,讓我們看看如何在我們的應(yīng)用程序中捕獲每個(gè)狀態(tài)。

          如何在代碼中捕獲生命周期狀態(tài)?

          你可以使用下面的JavaScript函數(shù)來確定一個(gè)給定頁面的主動(dòng)、被動(dòng)和隱藏狀態(tài)。

          1. const getState = () => {

          2. if (document.visibilityState === 'hidden') {

          3. return 'hidden';

          4. }

          5. if (document.hasFocus()) {

          6. return 'active';

          7. }

          8. return 'passive';

          9. };

          隨著Chrome 68的發(fā)布,開發(fā)者可以通過監(jiān)聽文檔對象上的凍結(jié)和恢復(fù)事件來觀察隱藏標(biāo)簽何時(shí)被凍結(jié)和解凍。

          1. document.addEventListener('freeze', (event) => {

          2. // The page is now frozen.

          3. });


          4. document.addEventListener('resume', (event) => {

          5. // The page has been unfrozen.

          6. });

          要確定一個(gè)頁面在隱藏標(biāo)簽頁中是否被丟棄,可以使用以下代碼。

          1. if (document.wasDiscarded) {

          2. // Page was previously discarded by the browser while in a hidden tab.

          3. }

          上面提到的wasDiscarded屬性可以在頁面加載時(shí)觀察。

          瀏覽器兼容性

          一些舊的瀏覽器不具備檢測其網(wǎng)頁何時(shí)被凍結(jié)或丟棄的能力。不過,隨著Chrome 68的發(fā)布,也加入了預(yù)測網(wǎng)頁下一步狀態(tài)的能力。

          已知的兼容性問題

          一些瀏覽器在切換標(biāo)簽頁時(shí)沒有觸發(fā)模糊事件,這樣可以避免頁面進(jìn)入被動(dòng)狀態(tài)。

          老版本的IE(10及以下)沒有實(shí)現(xiàn)visibilityChange事件。

          Safari在關(guān)閉標(biāo)簽頁時(shí)沒有可靠地觸發(fā)pagehide或visibilitychange事件。

          為了克服跨瀏覽器的不兼容性,Google開發(fā)了一個(gè)名為Pagelifecycle.js的庫,作為以下瀏覽器的多維填充。

          總結(jié)

          當(dāng)用戶沒有積極參與時(shí),網(wǎng)頁不應(yīng)該消耗過多的資源。此外,你的應(yīng)用程序還應(yīng)該知道系統(tǒng)執(zhí)行的管理任務(wù)。Page Lifecycle API介紹了一種簡單的方法來讓你的應(yīng)用程序知道這些事件。

          雖然它更多地與高級用例相關(guān),但我們可以通過了解它的功能來開發(fā)高效的網(wǎng)絡(luò)應(yīng)用。因此,我們可以為終端用戶提供更好的體驗(yàn)。

          點(diǎn)個(gè)『在看』支持下?

          瀏覽 52
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  最近中文字幕第三页 | 亚洲成人无码高清 | 欧美久久在线观看 | 插美女综合网 | 日本草逼视频 |