摘要:而且,在接下來頁面的異步請求中,還能進行緩存嘗試這里配置的文件清單在安裝激活階段不會進行緩存,只有在監聽到網絡請求的時候才進行緩存。
基本知識普及請參考
https://www.jianshu.com/p/623...
https://zhuanlan.zhihu.com/p/...
下面簡單介紹一下插件的使用
以下是我在項目中使用的配置
webpack.prod.conf.js中
{ ... plugins: [ new OfflinePlugin({ responseStrategy: "cache-first", // 緩存優先 AppCache: false, // 不啟用appCache safeToUseOptionalCaches: true, // Removes warning for about `additional` section usage autoUpdate: true, // 自動更新 caches: { // webpack打包后需要換的文件正則匹配 main: [ "**/*.js", "**/*.css", /.(png|jpe?g|gif|svg)(?.*)?$/, /.(woff2?|eot|ttf|otf)(?.*)?$/ ], additional: [ ":externals:" ] }, externals: [], // 設置外部鏈接,例如配置http://hello.com/getuser,那么在請求這個接口的時候就會進行接口緩存 excludes: ["**/.*", "**/*.map", "**/*.gz", "**/manifest-last.json"], // 需要過濾的文件 ServiceWorker: { output: "./static/sw.js", // 輸出目錄 publicPath: "/static/sw.js", // sw.js 加載路徑 scope: "/", // 作用域(此處有坑) minify: true, // 開啟壓縮 events: true // 當sw狀態改變時候發射對應事件 } }) ] }
在入口js文件中
OfflinePluginRuntime.install({ // 監聽sw事件,當更新ready的時候,調用applyUpdate以跳過等待,新的sw立即接替老的sw onUpdateReady: () => { console.log("SW Event:", "onUpdateReady") OfflinePluginRuntime.applyUpdate() }, onUpdated: () => { console.log("SW Event:", "onUpdated") window.swUpdate = true } })
首先介紹一下assets里面的三個屬性:
main: [] 這里配置的是serviceWorker在install階段需要緩存的文件清單,如果其中有一個失敗了,那么整個serviceWorder就會安裝失敗,所以必須謹慎配置
additional: [] 這里配置的文件清單會在serviceWorker activate的時候進行緩存,與main不一樣,如果這里的文件緩存失敗,不會影響serviceWorker的正常安裝。而且,在接下來頁面的ajax異步請求中,還能進行緩存嘗試
optional: [] 這里配置的文件清單在serviceWorker安裝激活階段不會進行緩存,只有在監聽到網絡請求的時候才進行緩存。
剛才說到作用域的時候有坑,如果按照上面的文件配置,最后在網頁中會提示,sw最大的作用域權限在/static下面,言外之意這么寫是無法將sw的作用域設置在/根路徑下面。
所以這邊需要服務端在返回sw.js的時候手動設置Service-Worker-Allowed頭字段,并且值設置為/,同時這個文件的緩存時間設為0,否則,當更新serviceWorker的時候,由于瀏覽器緩存了sw.js用戶端這邊的serviceWorker無法第一時間更新。
最后來一張線上項目,在網速極慢的情況下也能實現秒開
-------------------追加--------------------擴展fetch事件
首先在配置文件里添加入口
sw-entry.js
self.addEventListener("fetch", function (event) { function cachesMatch (request, cacheName) { return caches.match(request, { cacheName: cacheName }).then(function (response) { return response }) // Return void if error happened (cache not found) ["catch"](function () {}) } function cacheFirst(cacheUrl, CACHE_NAME) { var resource = cachesMatch(cacheUrl, CACHE_NAME).then(function (response) { if (response) { return response; } // Load and cache known assets var fetching = fetch(urlString).then(function (response) { if (!response.ok) { return response; } (function () { var responseClone = response.clone(); var storing = caches.open(CACHE_NAME).then(function (cache) { return cache.put(urlString, responseClone); }).then(function () { console.log("[SW]:", "Cache asset: " + urlString); }); event.waitUntil(storing); })(); return response; }); return fetching; }) return resource } function netWorkFirst(cacheUrl, CACHE_NAME) { var resource = fetch(cacheUrl).then(response => { if (response.ok) { var responseClone = response.clone() var storing = caches.open(CACHE_NAME).then(function (cache) { cache.put(cacheUrl, responseClone); }).then(function () { console.log("[SW]:", "Cache asset: " + cacheUrl); }); event.waitUntil(storing); return response; } // Throw to reach the code in the catch below throw new Error("Response is not ok"); }) ["catch"](function () { return cachesMatch(cacheUrl, CACHE_NAME); }); return resource } var url = new URL(event.request.url) url.hash = "" var pathname = url.pathname var urlString = url.toString() var cacheUrl = urlString var IS_KANO = /kano.guahao.cn/ var IS_STATIC = //static// var IS_HOME = /^/(e|u|n)/(d+)$/ var IS_EDITOR = /^/editor(?!.)/ var IS_PREVIEW = /^/preview(?!.)/ var CACHE_PREFIX = __wpo.name var CACHE_TAG = __wpo.version var CACHE_NAME = CACHE_PREFIX + ":" + CACHE_TAG var resource = undefined var isGET = event.request.method === "GET" // 以緩存優先的形式緩存 kano 以及 static/* 靜態資源 if ((cacheUrl.match(IS_KANO) || pathname.match(IS_STATIC)) && isGET) { resource = cacheFirst(cacheUrl, CACHE_NAME) event.respondWith(resource) } // 以網絡優先的形式緩存 editor頁面 preview頁面和 production頁面 if ((pathname.match(IS_HOME) || pathname.match(IS_EDITOR) || pathname.match(IS_PREVIEW)) && isGET) { resource = netWorkFirst(cacheUrl, CACHE_NAME) event.respondWith(resource) } })
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94157.html
摘要:配合的項,能夠實現緩存外部資源的功能。允許接受來自的消息,默認值為。檢查新版本的的更新信息。這也是我在研究階段直接使用時所發現的問題。建議僅在生產模式內使用。 showImg(https://segmentfault.com/img/bVSVG1?w=1178&h=484); 談起PWA,許多人可能還只停留在了解的層面,比較少在實踐中真正地嘗試過,更多的僅僅是對著網上的教程和例子大概玩...
摘要:本篇不包含所有坑,暫時只記錄自己踩到的部分坑一安裝安裝最新版本安裝新增依賴這個在中,本身和它的是在同一個包中,中將兩個分開管理。我記錄下自己更新這個的過程,以下前半部分可以直接跳過。以下記錄踩坑過程。 本篇不包含所有坑,暫時只記錄自己踩到的部分坑 一.安裝 安裝webpack4最新版本 npm install --save-dev webpack@4 安裝新增依賴 webpack-c...
摘要:和的關系不是一項技術,也不是一個框架,我們可以把她理解為一種模式,一種通過應用一些技術將在安全性能和體驗等方面帶來漸進式的提升的一種的模式。這里需要注意的是,首次注冊線程的頁面需要再次加載才會受其控制。 1. PWA和Service Worker的關系 PWA (Progressive Web Apps) 不是一項技術,也不是一個框架,我們可以把她理解為一種模式,一種通過應用一些技...
摘要:和的關系不是一項技術,也不是一個框架,我們可以把她理解為一種模式,一種通過應用一些技術將在安全性能和體驗等方面帶來漸進式的提升的一種的模式。這里需要注意的是,首次注冊線程的頁面需要再次加載才會受其控制。 1. PWA和Service Worker的關系 PWA (Progressive Web Apps) 不是一項技術,也不是一個框架,我們可以把她理解為一種模式,一種通過應用一些技...
閱讀 1008·2021-10-27 14:15
閱讀 2763·2021-10-25 09:45
閱讀 1921·2021-09-02 09:45
閱讀 3357·2019-08-30 15:55
閱讀 1798·2019-08-29 16:05
閱讀 3189·2019-08-28 18:13
閱讀 3109·2019-08-26 13:58
閱讀 442·2019-08-26 12:01