官方解释:https://angular.io/guide/service-worker-intro
使用目的:
提升用户体验,快速响应,使应用的访问体验接近于本地代码。
实现原理:
一个js脚本,作为请求代理,管理应用的缓存。
PWA 特点:
- 不仅能缓存应用发出的http请求,还能缓存静态资源,比如index.html文件;
- 即使关闭了窗口,缓存依然存在 (下一次打开浏览器,先加载pwa服务,服务拦截应用程序每个加载资源的请求),因此只要打开过应用,即使离线,下次也会看到页面内容,而不是"小恐龙";
- 此缓存不依赖服务器端指定的缓存标头;
- 一个缓存中的所有文件具有相同的版本号。 (也就是说,不会突然加载其他版本的文件,这样可能会导致不兼容)
- 访问程序的时候,会加载最新的完整下载的缓存版本;
- 程序的更新,是在后台悄悄发生的;
使用限制:
angular pwa 只用在 https 环境下用;
某些浏览器不支持;对于不支持service worker的浏览器,服务不会被加载,访问某些服务api会报错。
如何使用:
ng-cli 5.0 及以上的版本
ng add @angular/pwa
-
测试:
1、ng new my-app
2、ng add @angular/pwa
3、ng build
4、在 dist 文件夹下 http-server
5、打开浏览 localhost:8080, 可以访问
6、关闭 5 中的tab, 断网
7、打开一个窗口,输入 localhost:8080,可以看到正常的页面内容,而不是提示没有网络。
SwUpdate
限制:此方式只能照顾到已经打开过应用程序的用户;
// app.module.ts
@NgModule({
declarations: [
AppComponent
],
imports: [
// .. other imports
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production,
// 这里用 registerImmediately 比默认的好用
registrationStrategy: 'registerImmediately'
})
],
providers: [
AppUpdateService, // 监测更新服务
],
bootstrap: [AppComponent]
})
export class AppModule { }
/*
AppUpdateService.ts
*/
import { Injectable } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';
import { interval } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AppUpdateService {
isWorking = false;
constructor(updates: SwUpdate) {
console.log('init - appUpdateService .');
if (this.isWorking || !updates.isEnabled) {
return;
}
this.isWorking = true;
// 订阅
updates.available.subscribe(event => {
console.log(event);
if (event.current.hash !== event.available.hash) {
if (window.confirm('有新的更新可用,现在更新吗?')) {
updates.activateUpdate().then(() => document.location.reload());
}
}
});
updates.activated.subscribe((event) => {
console.log(event);
});
// 轮询
interval(1000 * 10).subscribe(() => {
updates.checkForUpdate().then( () => {
console.log('检查 .');
});
});
}
}
/*
* app.component.ts
*/
import { AppUpdateService } from 'src/service/appUpdate.service';
export class AppComponent {
// 实例化AppUpdateService
constructor (
private updateService: AppUpdateService
) {}
}