簡介
關於service worker,網絡上已經有了較多的文章。總的來說它依靠緩存資源,攔截http請求,來幫助我們達到離線使用網站的效果。
而angular cli爲了讓使用service worker更加便利,爲開發者提供了一個配置窗口(ngsw-config.json)和一個與service worker通訊的服務(SwUpdate)。
啓用
-
新建項目後在項目根目錄下鍵入
ng add @angular/pwa
。會爲你的項目添加一些文件,其中包括上文提到的ngsw-config.json,爲了即刻感受離線應用的魅力,現暫不需配置。
-
安裝http-server
npm install http-server -g
將用http-server啓用的服務器來加載應用,這麼做是爲了模擬真實的生產環境,因爲ng serve環境下無法啓用service worker。
- 鍵入
ng build --prod
進行打包。 打包完成後進入dist下的項目根目錄下,鍵入http-server -p <port>
將打包後的應用部署在http-server指定的端口上。 - 打開瀏覽器進入控制檯,以chrome爲例,在network選項卡上勾選offline模擬離線使用。
此時重新刷新網頁發現頁面依然能夠在離線狀態下顯示,說明service worker已經工作了。
配置
以上並沒有手動配置ngsw-config.json,然而初始的配置還有許多不足,比如無法攔截緩存api請求。因此需要對該文件的配置參數做一個大概瞭解(點擊瀏覽官方配置說明)。
參考官方的說明,我們瞭解到可以配置靜態資源的緩存策略(配置項中的assetGroups)以及動態資源的緩存策略(配置項中的dataGroups)。
靜態資源配置(assetGroups)
interface AssetGroup {
name: string;
installMode?: 'prefetch' | 'lazy';
updateMode?: 'prefetch' | 'lazy';
resources: {
files?: string[];
/** @deprecated As of v6 `versionedFiles` and `files` options have the same behavior. Use `files` instead. */
versionedFiles?: string[];
urls?: string[];
};
}
這是該配置項的接口,下面對各個屬性做一個簡要的說明:
- resources屬性下可配置本地的靜態資源(resources.files)和通過cdn來的靜態資源(resources.urls)
- name是需要編寫的該資源集合的唯一的名字
-
installMode配置的是你的網站應用第一次在當前瀏覽器加載後,service worker應該進行的緩存策略。
選擇'prefetch'會將resources列出的資源一股腦兒的預先緩存起來,不管當前是否有訪問到。選擇'lazy'則不會預先緩存,而是在用到時纔會進行緩存。
-
updateMode配置的是當檢測到資源的版本改變之後,所進行的資源緩存策略。
如何得知資源的版本發生了變化呢?angular service worker會對比資源內容的hash值。如果hash值不同則版本不同。選擇'prefetch'會立即緩存更新的資源,選擇'lazy'會在用到時在進行緩存。不過,這裏要注意如果在installMode的配置中沒有選擇'lazy'模式,則這裏的'lazy'模式也不會生效。
動態資源配置(dataGroups)
export interface DataGroup {
name: string;
urls: string[];
version?: number;
cacheConfig: {
maxSize: number;
maxAge: string;
timeout?: string;
strategy?: 'freshness' | 'performance';
};
}
這是緩存動態資源的配置項,其實就是緩存的ajax、fetch的response,將這些api請求的響應體進行緩存後,就可以在離線狀態下使用。其中:
- urls配置api的url
-
cacheConfig配置具體的緩存策略:
- maxSize 緩存的最大條目數或響應數,太多則會暫用系統資源
- maxAge 過期時間,該項與下面提到的strategy策略配合,如果設置過長,容易呈現老資源給用戶。
- timeout是指的應用發起真實網絡請求後的等待時間,如果超時將會配合下面提到的strategy進行動作
- strategy策略,選擇'performance'會直接攔截網絡請求,返回緩存(前提是有緩存,並且沒有超過maxAge的時間),選擇'freshness'會在timeout超時的時候返回緩存。
與service worker通訊
與service worker通訊可以讓我們主動做很多事情,而不是僅僅依賴於ngsw-config.json配置,通過依賴注入一個SwUpdate*服務,我們可以主動要求查詢、更新、激活應用的版本,(這部分內容筆者還未投入應用,詳見官網描述)
總結
這篇文章我們分享瞭如何在angular裏面使用service worker 進行離線場景的增強,其中包括
- 引入@angular/pwa
- 安裝http-server,模擬生產環境
- 配置ngsw-config.json 緩存策略
- 簡單描述了與service worker通訊的概念
相信今後angular框架能夠在pwa應用方便給我們更多的方便。