更新中css
提示:在測試程序的時候儘可能使用Chrome的隱身模式,確保 Service Worker 不會從之前的殘留狀態中讀取數據!!html
在sudo ng new pwa
新建工程以後,在工程的根目錄上運行sudo ng add @angular/pwa
,此時就會自動添加Service Worker文件,Manifest.json文件和各類不一樣尺寸的icon文件。 Angular PWA中文網傳送門web
在app.component.ts
中引入import { SwUpdate } from '@angular/service-worker';
來加載SW的更新模塊,每次PWA程序有更新均可以在這裏使用SwUpdate模塊獲取更新,並使用以下代碼可實現程序的更新操做:npm
export class AppComponent {
update: boolean;
constructor(updates: SwUpdate, private data: DataService) {
updates.available.subscribe( event => {
this.update = true;
updates.activateUpdate().then(() =>
document.location.reload()
);
}
);
}
title = 'PWA';
}
複製代碼
SwUpdate文檔傳送門json
而後在html中使用一個*ngIf
來判斷是否更新,(是則顯示text,不是則不顯示):api
<span *ngIf="update">There's an update associated with your progressive web application!</span>
複製代碼
每次更新了程序都要從新build production程序,在根目錄上運行sudo ng build --prod
,而後進入cd dist/PWA
,最後運行http-server -o
在服務器上運行更新後的程序。瀏覽器
因爲 ng serve
對 Service Worker
無效,因此必須用一個獨立的 HTTP 服務器在本地測試項目。 可使用任何 HTTP 服務器,我使用的是來自 npm 中的 http-server 包。固然也能夠自定義端口以防止port衝突:緩存
http-server -p 8080 -c-1 dist/<project-name>
複製代碼
注意: 若是想按期更新PWA,也就是使用interval建立一個週期輪詢方法,須要先讓應用註冊Aervice worker的進程進入穩定狀態,再讓它開始執行輪詢的過程,若是不斷輪詢更新(好比調用 interval())將阻止應用程序達到穩定態,也就永遠不會往瀏覽器中註冊 ServiceWorker 腳本。另外:應用中所執行的各類輪詢都會阻止它達到穩定態服務器
constructor(appRef: ApplicationRef, updates: SwUpdate) {
// Allow the app to stabilize first, before starting polling for updates with `interval()`.
const appIsStable$ = appRef.isStable.pipe(first(isStable => isStable === true));
const everySixHours$ = interval(6 * 60 * 60 * 1000);
const everySixHoursOnceAppIsStable$ = concat(appIsStable$, everySixHours$);
everySixHoursOnceAppIsStable$.subscribe(() => updates.checkForUpdate());
}
複製代碼
因此對於自動更新模塊的使用總結:網絡
constructor(appRef: ApplicationRef, updates: SwUpdate, private data: DataService) {
const appIsStable$ = appRef.isStable.pipe(first(isStable => isStable === true));
const everySixHours$ = interval(6 * 1000);
const everySixHoursOnceAppIsStable$ = concat(appIsStable$, everySixHours$);
everySixHoursOnceAppIsStable$.subscribe(() => {
updates.checkForUpdate();
// console.log('check update in Service Worker');
});
updates.available.subscribe(event => {
console.log('gotta new version here', event.available);
updates.activateUpdate().then(() => document.location.reload());
});
}
複製代碼
每6妙檢測一次更新版本,若是沒有updates.activateUpdate().then(() => document.location.reload());
則只是在檢測到新版本時候提醒並不刷新並更新程序。 測試的時候須要從新ng build --prod
而後http-server -p 8080 -c-1 dist/PWA
從新運行http服務器,這時候在原來的頁面上的console上就會發現出現了新版本的提醒。
(其實每次運行build命令都會出現版本更新不管是否更改代碼,當應用的一個新的構建發佈時,Service Worker 就把它看作此應用的一個新版本,版本是由 ngsw.json 文件的內容決定的,包含了全部已知內容的哈希值。 若是任何一個被緩存的文件發生了變化,則該文件的哈希也將在ngsw.json中隨之變化,從而致使 Angular Service Worker 將這個活動文件的集合視爲一個新版本)
全在nsgw-config.json
文件中定義PWA緩存,好比想緩存google的Montserrat字體和API地址,該文件中全部的代碼形式都是glob格式,也就是:
好比:
在實際代碼中這樣作:
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
複製代碼
在已經被建立的assetGroups
中添加:
"urls": [
"https://fonts.googleapis.com/**"
]
複製代碼
AssetGroup遵循的TypeScript接口規則爲:
interface AssetGroup {
name: string;
installMode?: 'prefetch' | 'lazy';
// prefetch 告訴 Angular Service Worker 在緩存當前版本的應用時要獲取每個列出的資源。 這是個帶寬密集型的模式,但能夠確保這些資源在請求時可用,即便瀏覽器正處於離線狀態
// lazy 不會預先緩存任何資源。相反,Angular Service Worker 只會緩存它收到請求的資源。 這是一種按需緩存模式。永遠不會請求的資源也永遠不會被緩存。 這對於像爲不一樣分辨率提供的圖片之類的資源頗有用,那樣 Service Worker 就只會爲特定的屏幕和設備方向緩存正確的資源。
updateMode?: 'prefetch' | 'lazy';
// prefetch 會告訴 Service Worker 當即下載並緩存更新過的資源
// lazy 告訴 Service Worker 不要緩存這些資源,而是先把它們看做未被請求的,等到它們再次被請求時才進行更新。
lazy 這個 updateMode 只有在 installMode 也一樣是 lazy 時纔有效。
resources: {
files?: string[];
/** @deprecated As of v6 `versionedFiles` and `files` options have the same behavior. Use `files` instead. */
versionedFiles?: string[];
urls?: string[];
};
}
複製代碼
在下方建立dataGroups
緩存API地址:
"dataGroups": [
{
"name": "jokes-api",
"urls": [
"https://api.chucknorris.io/jokes/random"
],
"cacheConfig": {
"strategy": "freshness",
"maxSize": 20,
"maxAge": "1h",
"timeout": "5s"
}
}
]
複製代碼
dataGroups的配置遵循下面的接口:
export interface DataGroup {
name: string;
urls: string[];
version?: number;
cacheConfig: {
maxSize: number;
maxAge: string;
timeout?: string;
strategy?: 'freshness' | 'performance';
};
}
複製代碼
其中的緩存設置中的幾個項目分別是: