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

資訊專欄INFORMATION COLUMN

[翻譯]Service workers:PWA背后的英雄

snifes / 432人閱讀

摘要:如果返回的被拒,另一個(gè)同步事件被自動(dòng)地開(kāi)始重試操作,直到返回一個(gè)成功狀態(tài)的。推送機(jī)制使得服務(wù)器能夠向發(fā)送信息,然后將信息展示給用戶才是消息通知。然后它們可以發(fā)送消息通知,或者是更新的狀態(tài)。

原文地址:https://medium.freecodecamp.org/service-workers-the-little-heroes-behind-progressive-web-apps-431cc22d0f16  
作者:Flavio Copes
摘要:這篇文章簡(jiǎn)述service worker作為PWA核心技術(shù)如何實(shí)現(xiàn)資源緩存和消息推送的功能,還幫助讀者理解service worker的生命周期。

Service worker是漸進(jìn)式網(wǎng)絡(luò)應(yīng)用(Progressive Web Apps)的核心。它們幫助我們實(shí)現(xiàn)原本是原生app才有資源緩存和消息推送兩大特性。

Service worker是你的網(wǎng)頁(yè)與網(wǎng)絡(luò)間的代理,它能夠攔截和緩存來(lái)往的網(wǎng)絡(luò)請(qǐng)求。這可以幫助你的應(yīng)用創(chuàng)造一個(gè)離線環(huán)境下也能良好訪問(wèn)的用戶體驗(yàn)。

首先介紹一下web worker的概念。它是一個(gè)與指定網(wǎng)頁(yè)相關(guān)聯(lián)的JS文件,獨(dú)立與主線程運(yùn)行在一個(gè)特定的上下文環(huán)境中,這樣就不會(huì)為了計(jì)算數(shù)據(jù)去犧牲UI的性能,從而避免了阻塞的情況。而service worker是一種特殊的web worker。

而正是由于它是一個(gè)子線程,所以無(wú)法操作DOM。同樣也無(wú)法訪問(wèn)Local Storage API和XHR API。它只能通過(guò)Channel Messaging API和主線程通信。

Service Worker能夠與下面幾個(gè)API合作:

Promises

Fetch API

Cache API

只有在HTTPS協(xié)議下的網(wǎng)頁(yè)里它們才會(huì)起作用。(不過(guò)不包括本地的網(wǎng)絡(luò)請(qǐng)求,因?yàn)樗鼈儾恍枰3职踩B接。這樣也方便我們調(diào)試。)

后臺(tái)進(jìn)程

Service worker能夠獨(dú)立于與它關(guān)聯(lián)的應(yīng)用程序運(yùn)行,并且在這些程序處于非活躍狀態(tài)下仍可以接收消息。

讓我來(lái)舉幾個(gè)場(chǎng)景:

app處于后臺(tái)非活躍狀態(tài)下運(yùn)行;

app被關(guān)閉;

呈現(xiàn)你網(wǎng)頁(yè)的瀏覽器被關(guān)閉;

那么service worker將不受影響地繼續(xù)工作。

Service worker的有用之處在于:

它們可以當(dāng)作緩沖層,處理網(wǎng)絡(luò)請(qǐng)求和緩存離線所需的資源;

它們可以用來(lái)推送消息。

Service worker只在需要的時(shí)候運(yùn)行,其他情況下都會(huì)停止工作。

支持離線

對(duì)于傳統(tǒng)網(wǎng)頁(yè),離線情況下的用戶體驗(yàn)非常糟糕。如果用戶沒(méi)有聯(lián)網(wǎng),移動(dòng)端的web應(yīng)用一般是直接停止工作。反觀原生應(yīng)用,會(huì)展示給用戶一些友好的提示信息。

下面這張圖是Chrome瀏覽器中離線網(wǎng)頁(yè)顯示的內(nèi)容,顯然這并不算是一個(gè)友好的提示信息:

也許唯一不錯(cuò)的地方是你可以通過(guò)點(diǎn)擊恐龍來(lái)免費(fèi)玩一個(gè)游戲,不過(guò)相信你很快就會(huì)變得不耐煩了。

不久之前,HTML5標(biāo)準(zhǔn)下的AppCache可以讓web應(yīng)用緩存離線資源,但是它缺乏靈活性并且有一些令人困惑的行為,這也說(shuō)明它無(wú)法勝任支持離線這項(xiàng)工作。

而現(xiàn)在,service worker成了離線緩存的新標(biāo)準(zhǔn)。

那么,它實(shí)現(xiàn)哪些緩存呢?

安裝時(shí)的預(yù)緩存

像圖片、CSS文件和JS文件都會(huì)在app的使用過(guò)程中重復(fù)用到。這些資源可以在app打開(kāi)的第一時(shí)間緩存好。

這也是所謂的APP殼架構(gòu)( App Shell architecture)的基礎(chǔ)。

緩存網(wǎng)絡(luò)請(qǐng)求

我們使用Fetch API可以對(duì)服務(wù)器返回的響應(yīng)報(bào)文進(jìn)行編輯,根據(jù)服務(wù)器是否可達(dá)來(lái)決定是否使用緩存中的響應(yīng)報(bào)文代替。

生命周期

一個(gè)service worker在啟動(dòng)前經(jīng)歷了三步:

注冊(cè)(Registration)

安裝(Installation)

激活(Activation)

注冊(cè)

注冊(cè)階段是通知瀏覽器service worker的存在,并且在后臺(tái)開(kāi)始安裝。

下面是寫(xiě)在worker.js中注冊(cè)一個(gè)service worker的代碼:

if ("serviceWorker" in navigator) { 
  window.addEventListener("load", () => {   
    navigator.serviceWorker.register("/worker.js") 
    .then((registration) => { 
      console.log("Service Worker registration completed with scope: ", registration.scope) 
    }, (err) => { 
      console.log("Service Worker registration failed", err)
    })
  })
} else { 
  console.log("Service Workers not supported") 
}

無(wú)論這段代碼被調(diào)用多少次,瀏覽器始終只會(huì)在service worker之前沒(méi)有注冊(cè)過(guò)或是需要更新的情況下進(jìn)入注冊(cè)階段。

Scope

register函數(shù)需要一個(gè)scope參數(shù)來(lái)指明你的web應(yīng)用被該service worker管理的文件所在路徑。

這個(gè)參數(shù)的默認(rèn)值是所有文件以及service worker文件父級(jí)目錄下的所有子文件夾。所以如果你把service worker文件放在根目錄下,它會(huì)管理整個(gè)web應(yīng)用。而如果在某個(gè)子文件夾中,它只會(huì)管理該路徑能夠訪問(wèn)的網(wǎng)頁(yè)。

下面這個(gè)例子通過(guò)指定scope參數(shù)為/notifications/目錄來(lái)注冊(cè)一個(gè)service worker。

navigator.serviceWorker.register("/worker.js", { 
  scope: "/notifications/" 
})

結(jié)尾的/非常重要,可以避免/notification頁(yè)面觸發(fā)service worker。而如果寫(xiě)成下面這樣:

{ scope: "/notifications" }

那么service worker就將同樣作用于/notification頁(yè)面。

注意:service worker無(wú)法控制自身所在目錄以外的文件。也就是說(shuō),如果service worker文件被放在/notification文件夾下,它無(wú)法控制根目錄/或其他不屬于/notification的文件。

安裝

如果瀏覽器發(fā)現(xiàn)一個(gè)service worker過(guò)期或之前沒(méi)有注冊(cè)過(guò),那么它將安裝這個(gè)service worker。

self.addEventListener("install", (event) => { 
  //... 
});

這是使用service worker初始化緩存,然后利用Cache API來(lái)緩存APP shell和靜態(tài)資源的好時(shí)機(jī)。

激活

一旦service worker注冊(cè)并安裝成功后 ,我們來(lái)到了第三階段:激活。

這時(shí),service worker能夠在加載新頁(yè)面時(shí)開(kāi)始工作。

它不能作用于激活前已經(jīng)加載過(guò)的頁(yè)面,所以只有重啟app或是刷新已加載頁(yè)面兩種方式來(lái)使它工作。

self.addEventListener("activate", (event) => { 
  //... 
});

監(jiān)聽(tīng)這個(gè)事件可以用來(lái)清除舊緩存或者是刪除新版service worker不需要的舊資源。

更新

你僅僅是修改一字節(jié)的文件就需要更新一次service worker。它會(huì)在注冊(cè)的代碼再次執(zhí)行時(shí)被更新。

更新后的service worker只有在所有頁(yè)面都被關(guān)閉后才開(kāi)始代替之前的service worker工作。如果僅僅是刷新頁(yè)面是不會(huì)起作用的,因?yàn)橹暗膕ervice worker仍然在運(yùn)行且沒(méi)有被刪除。

這種機(jī)制保證了更新不會(huì)讓之前在運(yùn)行的app或網(wǎng)頁(yè)崩潰。

Fetch事件

當(dāng)瀏覽器發(fā)送網(wǎng)絡(luò)請(qǐng)求時(shí)就會(huì)觸發(fā)Fetch事件。

我們借此可以在請(qǐng)求發(fā)送時(shí)檢查緩存中是否已經(jīng)存儲(chǔ)所需資源。

舉個(gè)例子,下面的代碼使用了Cache API來(lái)檢查請(qǐng)求的URL是否已經(jīng)被緩存。如果是,那么返回緩存中的響應(yīng)數(shù)據(jù),否則會(huì)發(fā)送請(qǐng)求然后返回響應(yīng)數(shù)據(jù)。

self.addEventListener("fetch", (event) => {
  event.respondWith( 
    caches.match(event.request) 
      .then((response) => { 
        if (response) { 
          //entry found in cache 
          return response 
        } 
        return fetch(event.request) 
      } 
    ) 
  ) 
})
Background Sync

當(dāng)用戶在離線狀態(tài)下發(fā)送網(wǎng)絡(luò)請(qǐng)求時(shí),Background Sync這個(gè)API將延遲該請(qǐng)求直到用戶脫離離線狀態(tài)。

這保證了用戶在離線狀態(tài)下仍然可以使用并操作app,這些離線操作會(huì)保存在隊(duì)列中,以便在連接網(wǎng)絡(luò)后向服務(wù)端發(fā)出響應(yīng)請(qǐng)求。(是不是比展示一個(gè)無(wú)休止的loading圖標(biāo)要好多了?)

navigator.serviceWorker.ready.then((swRegistration) => { 
    //注冊(cè)一個(gè)事件event1
  return swRegistration.sync.register("event1") 
});

下面的代碼是在service worker中監(jiān)聽(tīng)這個(gè)事件:

self.addEventListener("sync", (event) => { 
  if (event.tag == "event1") { 
    event.waitUntil(doSomething()) 
  } 
})

doSomething()返回一個(gè)promise。如果返回的promise被拒,另一個(gè)同步事件被自動(dòng)地開(kāi)始重試操作,直到返回一個(gè)成功狀態(tài)的promise。

這也使得app能夠在聯(lián)網(wǎng)時(shí)立刻更新服務(wù)器發(fā)來(lái)的數(shù)據(jù)。

消息推送

Service worker使得web應(yīng)用可以像原生一樣推送消息給用戶。

事實(shí)上,推送和消息通知是兩個(gè)不同的概念,它們組合而成的技術(shù)才是我們熟悉的消息推送。推送機(jī)制使得服務(wù)器能夠向service worker發(fā)送信息,然后service worker將信息展示給用戶才是消息通知。

由于service worker可以在app關(guān)閉后繼續(xù)運(yùn)行,所以它們能夠一直監(jiān)聽(tīng)推送事件。然后它們可以發(fā)送消息通知,或者是更新app的狀態(tài)。

推送事件會(huì)在后端通過(guò)瀏覽器推送服務(wù)后啟動(dòng),比如說(shuō)Firebase的推送服務(wù)。

下面的代碼演示了web worker如何監(jiān)聽(tīng)push事件:

self.addEventListener("push", (event) => { 
  console.log("Received a push event", event) 
  const options = { 
    title: "I got a message for you!", 
    body: "Here is the body of the message", 
    icon: "/img/icon-192x192.png", 
    tag: "tag-for-this-notification", 
  } 
  event.waitUntil( 
    self.registration.showNotification(title, options) 
  ) 
})
關(guān)于console.log

如果你的代碼中包含console.log或是其他類似的控制臺(tái)輸出語(yǔ)句,務(wù)必打開(kāi)Chrome開(kāi)發(fā)工具中的Preserve log功能。

否則的話,因?yàn)閟ervice worker在網(wǎng)頁(yè)加載前就開(kāi)始執(zhí)行,而此時(shí)控制臺(tái)會(huì)被清空,所以你無(wú)法看到任何日志輸出。

作者總結(jié)

非常感謝閱讀本篇教程,事實(shí)上,關(guān)于PWA還有很多要學(xué)習(xí)的知識(shí)。如果您有什么見(jiàn)解歡迎在下面評(píng)論。

譯者注:主流瀏覽器開(kāi)始逐漸支持service worker,以后PWA是否會(huì)真的與原生平分秋色呢?未來(lái)如何,我想現(xiàn)在多了解一點(diǎn)PWA的知識(shí)總不會(huì)壞事。  
項(xiàng)目地址:https://github.com/WhiteYin/translation

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

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

相關(guān)文章

  • PWA學(xué)習(xí)與實(shí)踐】(3) 讓你WebApp離線可用

    摘要:學(xué)習(xí)與實(shí)踐系列文章已整理至學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至。本文是學(xué)習(xí)與實(shí)踐系列的第三篇文章。引言其中一個(gè)令人著迷的能力就是離線可用。但是,如果你注意到文章開(kāi)頭的圖片就會(huì)發(fā)現(xiàn),離線時(shí)我們不僅可以訪問(wèn),還可以使用搜索功能。 《PWA學(xué)習(xí)與實(shí)踐》系列文章已整理至gitbook - PWA學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至learning-pwa-ebook。轉(zhuǎn)載請(qǐng)注明作者與出處。 本文是《PWA學(xué)習(xí)與實(shí)...

    since1986 評(píng)論0 收藏0
  • 翻譯 | Progressive Web AMPs

    摘要:小蘿卜滬江前端開(kāi)發(fā)工程師本文原創(chuàng)翻譯,有不當(dāng)?shù)牡胤綒g迎指出。簡(jiǎn)稱就非常擅長(zhǎng)做這些,事實(shí)這也是它們的宗旨。通過(guò)它精心設(shè)計(jì)的規(guī)則能保證優(yōu)先顯示頁(yè)面的主要內(nèi)容。原創(chuàng)新書(shū)移動(dòng)前端高效開(kāi)發(fā)實(shí)戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開(kāi)售。 小蘿卜(滬江前端開(kāi)發(fā)工程師)本文原創(chuàng)翻譯,有不當(dāng)?shù)牡胤綒g迎指出。轉(zhuǎn)載請(qǐng)指明出處。 如果你在過(guò)去幾個(gè)月一直關(guān)注web開(kāi)發(fā)社區(qū),你很可能已經(jīng)閱讀了 progressive web ap...

    miracledan 評(píng)論0 收藏0
  • 構(gòu)建離線web應(yīng)用(一)

    摘要:我喜歡移動(dòng),而且也是那些堅(jiān)持使用技術(shù)構(gòu)建移動(dòng)應(yīng)用程序的人之一。我們準(zhǔn)備做這樣的一個(gè)漸進(jìn)式應(yīng)用是典型的旨在提高用戶離線體驗(yàn)的應(yīng)用。當(dāng)我們開(kāi)始構(gòu)建應(yīng)用時(shí),你就能理解上面的場(chǎng)景了。的作用范圍是針對(duì)相對(duì)路徑的。最佳的做法是在應(yīng)用的入口。 我喜歡移動(dòng)app,而且也是那些堅(jiān)持使用Web技術(shù)構(gòu)建移動(dòng)應(yīng)用程序的人之一。 經(jīng)過(guò)技術(shù)的不斷迭代(可能還有一些其它的東西),移動(dòng)體驗(yàn)設(shè)計(jì)愈來(lái)愈平易近人,給予用戶...

    Sanchi 評(píng)論0 收藏0
  • 前端應(yīng)該知曉PWA

    摘要:對(duì)來(lái)說(shuō)主要兩個(gè)事件。是當(dāng)前的變量,執(zhí)行該方法表示強(qiáng)制當(dāng)前處在狀態(tài)的進(jìn)入狀態(tài)。頁(yè)面關(guān)閉之后,老的會(huì)被干掉,新的接管頁(yè)面新的生效后會(huì)觸發(fā)事件。 一、傳統(tǒng)web 應(yīng)用 當(dāng)前web應(yīng)用在移動(dòng)時(shí)代并沒(méi)有達(dá)到其在桌面設(shè)備上流行的程度,下面有張圖來(lái)對(duì)比與原生應(yīng)用之間的差別。 showImg(https://segmentfault.com/img/bVbaD44?w=1920&h=1080)...

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

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

0條評(píng)論

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