js構建離線應用

內容主要引用自吳浩麟著《webpack深刻淺出》

離線應用

離線應用的優勢:
在沒有網絡的狀況下能打開網頁。
因爲部分緩存的資源直接從本地加載,因此對用戶來講能夠加快網頁的加載速度,減小服務器壓力。

技術實現:

離線應用的核心是離線緩存技術,歷史上曾前後出現兩種離線緩存技術。webpack

  • AppCache:又叫作Application Cache,目錄已經從web標準中刪除,儘可能不要使用。
  • Service Workers:目前最新的離線緩存技術,是Web Worker的一部分,它經過攔截網絡請求實現離線緩存,比 AppCache更靈活。由於它能夠經過js代碼去控制緩存的邏輯。

Service Workers

Service Workers是一個在瀏覽器後臺運行的腳本,它的生命週期徹底獨立於網頁,它沒法直接訪問DOM。它能夠經過postMessage接口發送消息來和UI進程通訊。

攔截網絡功能是Service Workers的重要功能。經過Service Workers能完成離線緩存,編輯響應,過濾響應等功能。web

目前Chrome,Firefox,Opera都已經全面支持Service Workers。但只有高版本的Android支持移動端的瀏覽器。,因爲Service Workers沒法經過注入Polyfill實現兼容,因此在打算使用它前,請先確認本身的網頁的運行場景。chrome

注:Polyfill:
墊片,就是幫你加一層東西來解決問題,不光是兼容性問題,pollyfill是個概念舉個例子,有些舊瀏覽器不支持Number.isNaN方法,Polyfill就能夠是這樣的瀏覽器

·if(!Number.isNaN) {
    Number.isNaN = function(num) {
        return(num !== num);
    }
}·

啥意思呢,就是假如瀏覽器沒有Number.isNaN方法,那我們就給它添加上去,所謂Polyfill就是這樣解決API的兼容問題的。
判斷瀏覽器是否支持Service Workers的最簡單方法是經過如下代碼:
if(navigator.serviceWorker){alert(true)}緩存

註冊Service Workers

要爲網頁接入Service Workers,須要在網頁加載後註冊一個描述Service Workers邏輯的腳本,代碼以下:服務器

`if(navigator.serviceWorker)
{
    window.addEventListener('DOMContentLoaded',function(){
        navigator.serviceWorker.register('./sw.js')
    })
}`

一旦這個腳本文件被加載,Service Workers的安裝就開始了,在這個腳本被安裝到瀏覽器中後,
就算是用戶關閉了當前網頁,它仍會存在,也就是第一次打開該網頁時,Service Workers的邏輯不會生效。
由於腳本尚未被加載和註冊,可是之後再次打開該網頁時腳本里的邏輯將會生效。網絡

在Chrome中能夠經過打開網址chrome://inspect/#service-workers來查看當前瀏覽器中全部已註冊的Service Workers。post

更新緩存

瀏覽器針對Service Workers有以下機制:
  • 每次打開接入了Service Workers的網頁時,瀏覽器都會從新下載Service Workers腳本文件,因此要注意該腳本文件不要太大,若是發現和當前已經註冊過的文件存在字節差別,就將其視爲「新服務工做線程」。
  • 新的Service Workers線程將會啓動,且將會觸發其install事件。
  • 當網站上當前打開的頁面關閉時,舊的Service Workers線程將會被終止,新的Service Workers線程將會取得控制權。
  • 新的Service Workers線程取得控制權後,將會觸發其activate事件。
  • 新的Service Workers線程中的activate事件就是清理舊緩存的最佳時間點網站

    Service Workers在註冊成功後會在其生命週期中派發一些事件,經過監聽對應的事件,在特定的時間上作一些事情。ui

    在Service Workers腳本中引入了新的關鍵字self,表明當前的Service Workers實例。

    在Service Workers安裝成功後會派發出install事件,須要在這個事件中執行緩存資源的邏輯。

接入webpack

用webpack構建接入Service Workers的離線應用時,要解決的問題在於如何生成以前提到的sw.js文件。
而且sw.js文件中的cacheFileList變量,表明須要被緩存文件的URL列表,須要根據輸出文件列表所對應的URL來決定。而不是寫成靜態值。

webpack沒有原生功能能夠完成以上需求,可使用插件serviceworker-webpack-plugin
·

const ServiceWorkerWebpackPlugin=require('serviceworker-webpack-plugin')
    new ServiceWorkerWebpackPlugin({
            // 自定義的 sw.js 文件所在路徑
            // ServiceWorkerWebpackPlugin 會把文件列表注入到生成的 sw.js 中
            entry: path.join(__dirname, 'sw.js'),
        })
    devServer: {
        //Service Workers依賴HTTPS,使用DevServer提供的HTTPS功能。
        https:true
    }

·
在目錄下新建sw.js文件,手動寫手更新緩存裏的代碼,。

serviceworker-webpack-plugin爲了保證靈活性,容許使用都自定義sw.js,構建輸出的sw.js文件中會在頭部注入一個變量serviceWorkerOption.assets到全局,裏面存放着全部須要被緩存的文件的URL列表。

須要將sw.js裏的文件列表變量寫成動態的
·

var cacheFileList=global.serviceWorkerOption.assets

在main.js代碼中註冊:
if (navigator.serviceWorker) {
    window.addEventListener('DOMContentLoaded',function() {
        // 調用 serviceWorker.register 註冊,參數 /sw.js 爲腳本文件所在的 URL 路徑
        navigator.serviceWorker.register('sw.js');
    });
}

·

**注:使用Service Workers技術須要依賴HTTPS,可使用DevServer提供的HTTPS功能。DevServer會自動生成一份HTTPS證書。**

相關文章
相關標籤/搜索