PWA(Progressive Web App)是前端的大趨勢,它能極大的加快前端頁面的加載速度,獲得近乎原生 app 的展現效果(其實難說)。PWA 實際上是多種前端技術的組合,其中最重要的一個技術就是 service worker。html
Service worker 在 MDN 上的說明:前端
Service workers 本質上充當Web應用程序與瀏覽器之間的代理服務器,也能夠在網絡可用時做爲瀏覽器和網絡間的代理。它們旨在(除其餘以外)使得可以建立有效的離線體驗,攔截網絡請求並基於網絡是否可用以及更新的資源是否駐留在服務器上來採起適當的動做。他們還容許訪問推送通知和後臺同步API。
其實不用太糾結,簡單起見咱們就把它當成更高級更先進的 AppCache 就行了。node
借近期公司官網升級之機,我也給公司官網上了 Service worker 作離線緩存。git
大前提:Service worker 只可在 https(或 localhost)下使用,首先確保你的網站上了 httpsgithub
在 nuxt 程序中啓用 Service worker 很是方便。nuxt 提供了官方 module——pwa-module 用於支持 PWA 網站,其中就包含了用於實現 Service worker 的 workbox module。workbox 其實是指的 google 爲簡化 Service worker 開發而開源的第三方庫。web
首先安裝依賴shell
$ yarn add @nuxtjs/pwa @nuxtjs/workbox
而後再配置文件中啓用瀏覽器
// modules module.exports = { [ '@nuxtjs/pwa' ] }
就完成了緩存
官網上線後發現,啓用 Service worker 後 Safari 不能播放視頻了。可是直接輸入視頻連接卻能夠播放。通過各類 google 搜索查資料後找到了官方 issue:服務器
甚至還找到了有人給 webkit(Safari 瀏覽器內核)開了bug:https://bugs.webkit.org/show_...
狀態始終是 new,沒有人解決。但 issue 中詳細說明了 Safari 的行爲以及產生問題的緣由
問題的緣由在於對於視頻文件請求,瀏覽器會發出帶有 Range 頭的請求部分獲取文件內容。Safari 比較奇葩,對於視頻文件請求,它一開始就會發一個 Range: 0-1
的請求,可是 Service worker 中處理請求的邏輯不能識別 Range
請求,把 Range
請求當成普通請求處理,返回了 200。Safari 把 200 當成了失敗請求,致使請求視頻文件失敗。
最後開各人的回帖找到了這裏:https://developers.google.com...
而後通過各類嘗試(中間過程略),說一下可行方案:
首先添加 js plugin:
// workbox-range-request.js workbox.routing.registerRoute( /.*\.(mp4|webm)/, workbox.strategies.cacheFirst({ plugins: [ new workbox.rangeRequests.Plugin(), ], }), 'GET' );
這個文件給 workbox 註冊一個路由,指定對於視頻文件(以 .mp4 或 .webm 結尾的文件。若是你的網站有音頻文件也要一併處理)處理程序添加 rangeRequests
插件
而後在配置文件中註冊插件:
// modules: [ '@nuxtjs/pwa', { workbox: { cachingExtensions: '@/plugins/workbox-range-request.js', } } ],
注意必須使用 cachingExtensions
而不能用 routingExtensions
,雖然註冊的是路由配置
這樣 Service worker 就能夠處理帶 Range
頭的請求了,可是還不算完。workbox 會請求 googlecdn 動態加載 js 腳本,若是你身在兲朝,因爲衆所周知的緣由加載腳本會失敗。
解決方案:
static
文件夾下,筆者是 static/workbox-v3.5.0
// modules: [ '@nuxtjs/pwa', { meta: false, workbox: { config: { modulePathPrefix: '/workbox-v3.5.0' }, cachingExtensions: '@/plugins/workbox-range-request.js', } } ],
配置中指定 workbox 從 /workbox-v3.5.0
這個路徑加載 js 腳本,而不走 googlecdn。
注意配置中使用的 config
當前版本(@nuxtjs/pwa@2.5.0, 2018-09-20)還不支持,筆者給官方倉庫開了 Pull request 還在審覈中,筆者是直接修改了 node_modules
裏的文件。
在上 Service worker 以前最好想清楚。這玩意和 AppCache 同樣,上線簡單,想要下線就難了
請上公司官網體驗效果:https://www.eoitek.com