老虎證券web端PWA實踐總結

柳菁發表於2018-07-10

    歷時兩個月,PWA功能終於在web端穩定落地使用,網站 web.itiger.com

    從最新研究到落地上線,遇到不少坑;開發過程中也參考了不少資料,但總有那麼幾個是沒有答案,需要自己摸索結果的。所以,寫了這篇總結文章,也闡述一下我在開發過程中遇到的問題,以及解決辦法。

  1. 開發環境:vue+webpack,因為專案需要,vue版本v2.5.8,webpack版本v3.8.1

  1. Manifest.json配置

Manifest.json檔案配置的屬性是根據manifest的API完成的,其中稍作修改的有兩處。改動的原因:webpack打包後的static檔案路徑(https://static.itiger.com)和真正的訪問路徑(https://web.itiger.com)是在兩個不同的二級域名下,屬於跨域,所以對manifest的icon和引入路徑稍加配置。

老虎證券web端PWA實踐總結

(from: web.itiger.com )

1). icon的src屬性配置

因為將Manifest.json檔案放在static下,加上webpack的配置原因,icon圖片的路勁會稍有不同,為了避免錯誤和麻煩,直接將圖片轉成了base64編碼,也可以省去向伺服器請求icon圖片的時間,不佔用頻寬(如果圖片較小,頻寬的影響是可以忽略的)。

2). webpack打包後,manifest.json引入路徑

Manifest.json是在index.html內用link標籤引入的,如下所示:

<link rel="manifest" href="/manifest.json?<%=Date.now() %>">

(後面的引數:用打包時間做版本號識別)

但是manifest.json是放在/static資料夾下,經過webpack打包,正常來說也會在/dist/static資料夾下,但考慮上述提到的跨域問題,需要通過webpack(var CopyWebpackPlugin = require('copy-webpack-plugin'))引用依賴進行配置,將manifest.json檔案打包到/dist目錄下,便於訪問。

plugins: [

new CopyWebpackPlugin([

from: resolve('static/manifest.json'),

to: resolve('dist/manifest.json')

}

])

]

  1. Service worker配置

Service worker 的安裝註冊,是跟所有教程一樣的,不做贅述。可以在這裡進行查閱。

在本專案中,靜態快取借用了workbox-webpack-plugins,service worker.js內有手寫部分,所以沒有采用workbox 的GenerateSW()方法自動生成,而是用的InjectManifest(),對已有的sw.js檔案進行編輯。

因為workbox是存放在google的cdn上,考慮到客戶翻牆問題,就把workbox下載並傳到了tiger cdn上,所以,這邊涉及到workbox的import問題:

如果是從google的cdn引入,則webpack配置時importWorkboxFrom : cdn;

如果是從專案本地引入,則importWorkboxFrom : local;

如果是從其他地方(如tiger cdn)引入,則importWorkboxFrom : disabled,並且在service worker.js檔案內手動配置 importscript( ) 以及 workbox.core.setCacheNameDetails( ) 屬性。

一開始,是考慮將workbox安裝包放在專案內,但安裝包不小,所以放棄了這種方法改用放在tiger cdn上。但是剛開始的配置是importWorkboxFrom : cdn,所以導致service worker.js檔案中出現兩個workbox的引入路徑,造成引入失敗;最終將importWorkboxFrom設定成disabled就解決了。

  1. IndexedDB和Cache Storage快取清理

1). Cache storage實時更新資料時清除舊快取

Cachestorage 中會有三個快取,其中預快取內容存放在***-precache內

老虎證券web端PWA實踐總結

在進行靜態資源快取時,快取策略總會有選擇staleWhileRevalidate()的時候,此時的請求結果快取在***-runtime內,但會帶來一個快取問題。

用staleWhileRevalidate( )屬性所配置的靜態檔案,會從cache storage訪問,同時從network進行請求獲得最新的資料並更新cache的內容

老虎證券web端PWA實踐總結

(from: developers.google.com/web/fundame…)

Runtime-cache的內容永遠保持最新,但是之前的就快取也沒有被刪除,會導致本地快取量一直增加。

解決辦法:每次service worker被啟用時('activate',如重新整理頁面),新得到的請求結果在就快取被刪除後(waitUntil( ))再儲存

this.addEventListener('activate', function(event) {

var cacheWhitelist = [workbox.core.cacheNames.runtime];

event.waitUntil(

caches.keys().then(function(keyList) {

return Promise.all(keyList.map(function(key) {

if (cacheWhitelist.indexOf(key) >= 0) {

return caches.delete(key);

}

}))

})

)

})

2). 清除快取

當indexedDB和cache storage全部清空時,service worker.js 執行也不再有意義,所以要將service worker解除安裝,並重新改下載註冊。

if (window.navigator && navigator.serviceWorker) {

navigator.serviceWorker.getRegistrations()

.then(registrations => {

for (let registration of registrations) {

registration.unregister()

}

})

}

解除安裝之後再清空indexedDB和cache storage

indexedDB.deleteDatabase('indexedDB的名稱')

caches.keys().then((keyList) => {

if (!keyList.length) return

keyList.map((item) => {

caches.delete(item)

})

})

以上是該專案在落地PWA時遇到的一些坑和大家分享,有什麼問題的歡迎指正。



相關文章