您可以已曉得,漸進式Web運用(PWA)會愈來愈受歡迎,因為它們旨在使Web運用的用戶體驗越發流通,建立Native運用程序般的體驗,而不只是運轉在瀏覽器的運用。構建漸進式Web運
您可以已曉得,漸進式Web運用(PWA)會愈來愈受歡迎,因為它們旨在使Web運用的用戶體驗越發流通,建立Native運用程序般的體驗,而不只是運轉在瀏覽器的運用。
構建漸進式Web運用程序的重要緣由之一是使運用在收集和加載方面異常牢靠 – 它應當可用於不確定或不存在的收集前提。
在這篇文章中,我們將深入探討Service Worker:他們怎樣運作以及應當注重的處所。末了,我們還列出了您應當應用的Service Workers的一些奇特上風。
概述
假如你想相識關於Service Workers的統統,你應當起首瀏覽本系列第幾篇文章。
基本上,Service Worker是一種收集工作者,更具體地說,它就像一個Shared Worker:
- Service Worker在它自己的全局劇本高低文中運轉
- 它沒有綁定到特定的網頁
- 它沒法接見DOM
Service Worker API令人興奮的重要緣由之一是它可以讓你的收集運用程序支撐離線體驗,從而使開發人員可以完整掌握流程。
Service Worker 的生命周期
Service Worker生命周期與您的網頁是完整離開。它由以下幾個階段構成:
下載
這是瀏覽器下載包括Service Worker的.js文件的時刻。
裝置
您的Web運用程序想要裝置Service Worker,您必須先註冊它,您可以在Javascript代碼中舉行註冊。當Service Worker被註冊時,它會提醒瀏覽器在背景啟動Service Worker裝置步驟。
經由歷程註冊Service Worker,你可以關照瀏覽器你的Service Worker的Javascript文件在那裡。我們來看下面的代碼:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// 註冊勝利
console.log('ServiceWorker registration successful');
}, function(err) {
// 註冊失利
console.log('ServiceWorker registration failed: ', err);
});
});
}
該代碼搜檢當前環境中是不是支撐Service Worker API。假如支撐,則註冊/sw.js Service Worker。
您可以在每次加載頁面時挪用register()要領而不必憂鬱 – 瀏覽器會推斷Service Worker是不是已註冊,而且會正確處置懲罰。
register()要領的一個重要細節是Service Worker文件的位置。在這類狀況下,您可以看到效勞工作者文件位於域的根目錄。這意味着Service Worker的局限將是全部泉源。換句話說,這個Service Worker將會收到這個域的一切東西的fetch事宜(我們將在背面議論)。假如我們在/example/sw.js註冊Service Worker文件,那末效勞工作者將只能看到URL以/example/(即/example/page1/,/example/page2/)開首的頁面的fetch事宜。
在裝置階段,最好加載和緩存一些靜態資本。資本勝利緩存后,Service Worker裝置完成。假如沒有勝利(加載失利) – Service Worker將重試。一旦裝置勝利,您將曉得靜態資本位於緩存中。
在裝置階段,最好加載和緩存一些靜態資本。資本勝利緩存后,Service Worker裝置完成。假如沒有勝利(加載失利) – Service將重試。一旦裝置勝利,您將曉得靜態資產位於緩存中。
假如註冊須要在加載事宜以後發作,這將回覆您的題目。這不是必須的,但它是相對引薦的。
為何如許?讓我們斟酌用戶第一次接見您的收集運用程序。如今還沒有Service Worker,瀏覽器沒法事前曉得是不是會有裝置的Service Worker。假如裝置了Service Worker,則瀏覽器須要為這個分外的線程消費分外的CPU和內存,不然瀏覽器將消費在襯着網頁上。
最重要的是,假如你只是在你的頁面上裝置一個Service Worker,你可以會有耽誤加載和襯着的風險 – 而不是儘快讓你的用戶可以運用這個頁面。
請注重,這僅在第一次接見頁面時才顯得重要。後續頁面接見不受Service Worker裝置的影響。一旦在第一次接見頁面時激活Service Worker,它可以處置懲罰加載/緩存事宜,以便隨後接見您的Web運用程序。這統統都是有原理的,因為它須要準備好處置懲罰有限的收集銜接。
激活
裝置Service Worker以後,下一步是將其激活。這一步是治理之前緩存的好機會。
一旦激活,Service Worker將最先掌握一切屬於其局限的頁面。一個風趣的事實是:初次註冊Service Worker的頁面將不會被掌握,直到該頁面再次被加載。一旦處於Service Worker掌握之下,它將處於以下狀況之一:
- 它將處置懲罰從頁面發出收集請求或音訊時發作的fetch和message事宜
- 它將被住手以節約內存
以下是生命周期的表面:
在ervice Worker內部處置懲罰裝置
在頁面加快註冊歷程以後,讓我們看看Service Worker劇本中發作了什麼,它經由歷程向Service Worker實例增加事宜偵聽器來處置懲罰install事宜。
這些是install事宜處置懲罰時須要採用的步驟:
- 翻開緩存
- 緩存我們的文件
- 確認是不是緩存了一切必須的資本
這是一個簡樸的install在Service Worker內:
var CACHE_NAME = 'my-web-app-cache';
var urlsToCache = [
'/',
'/styles/main.css',
'/scripts/app.js',
'/scripts/lib.js'
];
self.addEventListener('install', function(event) {
// event.waitUntil takes a promise to know how
// long the installation takes, and whether it
// succeeded or not.
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
假如一切文件勝利被緩存,Service Worker會被裝置。假如任何文件下載失利,install步驟會失利。所以重要注重你須要緩存的文件。
處置懲罰install事宜是可選的,你可以防止處置懲罰它。在這類狀況下,上面三個步驟你都無需處置懲罰。
在運轉時緩存請求
這部份是關鍵地點。這裏您將看到怎樣阻攔請求並返回建立的緩存(並建立新緩存)。
裝置Service Worker而且用戶導航到另一個頁面或革新他地點的頁面后,Service Worker將收到fetch事宜。下面是一個演示怎樣返回緩存資本或實行新請求然後緩存效果的示例:
self.addEventListener('fetch', function(event) {
event.respondWith(
// This method looks at the request and
// finds any cached results from any of the
// caches that the Service Worker has created.
caches.match(event.request)
.then(function(response) {
// If a cache is hit, we can return thre response.
if (response) {
return response;
}
// Clone the request. A request is a stream and
// can only be consumed once. Since we are consuming this
// once by cache and once by the browser for fetch, we need
// to clone the request.
var fetchRequest = event.request.clone();
// A cache hasn't been hit so we need to perform a fetch,
// which makes a network request and returns the data if
// anything can be retrieved from the network.
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Cloning the response since it's a stream as well.
// Because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have two streams.
var respOnseToCache= response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
// Add the request to the cache for future queries.
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
簡而言之,這就是發作的歷程:
- event.respondWith()將決議我們怎樣相應fetch事宜。我們傳遞了一個來自caches.match()的promise,它檢察請求並發現是不是有任何已建立的緩存的緩存效果。
- 假如存在緩存,則返回效果。
- 不然,將實行fetch事宜。
- 搜檢狀況是不是為200。我們還搜檢相應範例是不是basic,這表明它是來自我們origin的請求。在這類狀況下,不會緩存對第三方資本的請求。
- 相應效果被增加到緩存中。
要乞降相應必須被克隆,因為它們是流。流的主體只能被運用一次。而且因為我們想要運用它們,瀏覽器也要運用它們,所以必須克隆它們。
更新效勞工作者
當用戶接見您的Web運用程序時,瀏覽器會嘗試從新下載包括Service Worker代碼的.js文件。這發作在背景。
假如與當前Service Worker的文件比擬,如今下載的Service Worker文件中以至存在單字節差別,則瀏覽器將假定有轉變而且必須啟動新的Service Worker。
新的Service Worker將啟動而且install事宜將被觸發。然則,在這一點上,舊的Service Worker仍在掌握你的收集運用程序的頁面,這意味着新的Service Worker將進入waiting狀況。
一旦您的Web運用程序當前翻開的頁面封閉,舊的Service Worker將被瀏覽器住手,新裝置的Service Worker將完整掌握。這是當它的激活事宜將被觸發。
為何須要這些?為了防止兩個版本的Web運用程序同時運轉在差別的選項卡上 – 這在收集上實際上異常罕見,而且可以會建立異常蹩腳的毛病(比方,在瀏覽器中存儲數據時存在差別形式的狀況)。
從緩存中刪除數據
activate回調中最罕見的步驟是緩存治理。你如今要如許做,因為假如你在裝置步驟中刪除了一切舊的緩存,舊的Service Workers將倏忽住手供應緩存中的文件。
下面是一個示例,您可以從緩存中刪除某些未列入白名單的文件(在這類狀況下,其稱號中包括page-1或page-2):
self.addEventListener('activate', function(event) {
var cacheWhitelist = ['page-1', 'page-2'];
event.waitUntil(
// Retrieving all the keys from the cache.
caches.keys().then(function(cacheNames) {
return Promise.all(
// Looping through all the cached files.
cacheNames.map(function(cacheName) {
// If the file in the cache is not in the whitelist
// it should be deleted.
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
});
HTTPS請求
在構建Web運用程序時,您可以經由歷程當地主機運用Service Worker,然則一旦將其布置到臨盆環境中,則須要準備好HTTPS(這是您具有HTTPS的末了一個緣由)。
運用Service Worker,您可以挾制銜接並製造相應。 經由歷程不運用HTTPs,您的Web運用程序變得輕易遭到進擊。
為了讓事變更平安,您須要在經由歷程HTTPS供應的頁面上註冊Service Worker,以便您曉得瀏覽器吸收的Service Worker在經由歷程收集中未被修正。
瀏覽器支撐
效勞人員的瀏覽器支撐正在變得愈來愈好:
Service Worker運用場景
Service Worker供應的一些奇特功用是:
- 推送關照 – 許可用戶挑選從收集運用程序實時更新。
- 背景同步 – 許可您推延操縱,直到用戶具有穩固的銜接。如許,您可以確保不管用戶想要發送什麼,實際上都邑發送。
- 按期同步(未支撐) – 供應治理按期背景同步功用的API。
- Geofencing(將來支撐) – 您可以定義參數,也稱為繚繞感興趣地區的地輿圍欄。當裝備逾越地輿圍欄時,Web運用程序會收到關照,這可以讓您依據用戶的地輿位置供應有效的體驗。