angular-pwa

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

@angular/pwa

@angular/pwa

Version: Angular 21 (2025) Tags: PWA, Service Worker, Offline, Web App Manifest
References: PWA Guidengsw-config
版本: Angular 21 (2025) 标签: PWA、Service Worker、离线、Web App Manifest
参考资料: PWA指南ngsw-config

API Changes

API 变更

This section documents recent version-specific API changes.
  • NEW: Angular Service Worker v2 — Improved caching strategies
  • NEW: esbuild PWA support — Faster builds
  • NEW: @angular/build:application — Modern PWA building
本部分记录了近期特定版本的API变动。
  • 新增:Angular Service Worker v2 — 改进的缓存策略
  • 新增:esbuild PWA支持 — 更快的构建速度
  • 新增:@angular/build:application — 现代化PWA构建能力

Best Practices

最佳实践

  • Add PWA to project
bash
ng add @angular/pwa
  • Configure ngsw-config.json
json
{
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/*.css",
          "/*.js"
        ]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(svg|cur|jpg|jpeg|png)"
        ]
      }
    }
  ],
  "dataGroups": [
    {
      "name": "api-freshness",
      "urls": ["/api/**"],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize": 100,
        "maxAge": "1h",
        "timeout": "10s"
      }
    }
  ]
}
  • Use network-first for API calls
json
{
  "dataGroups": [
    {
      "name": "api",
      "urls": ["/api/**"],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize": 50,
        "maxAge": "1h"
      }
    }
  ]
}
  • Use cache-first for static assets
json
{
  "assetGroups": [
    {
      "name": "static",
      "installMode": "prefetch",
      "updateMode": "prefetch",
      "resources": {
        "files": ["/*.js", "/*.css"]
      }
    }
  ]
}
  • Handle offline state
ts
import { SwPush } from '@angular/service-worker';

constructor(private swPush: SwPush) {}

subscribeToNotifications() {
  if (this.swPush.isEnabled) {
    this.swPush.requestSubscription({
      serverPublicKey: 'VAPID_PUBLIC_KEY'
    });
  }
}
  • Check service worker updates
ts
import { SwUpdate } from '@angular/service-worker';

constructor(private updates: SwUpdate) {
  this.updates.versionUpdates.subscribe(event => {
    if (event.type === 'VERSION_READY') {
      // Reload to get new version
      window.location.reload();
    }
  });
}
  • Customize manifest
json
{
  "name": "My PWA",
  "short_name": "MyPWA",
  "theme_color": "#1976d2",
  "background_color": "#ffffff",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "icons": [
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ]
}
  • 为项目添加PWA
bash
ng add @angular/pwa
  • 配置ngsw-config.json
json
{
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/*.css",
          "/*.js"
        ]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(svg|cur|jpg|jpeg|png)"
        ]
      }
    }
  ],
  "dataGroups": [
    {
      "name": "api-freshness",
      "urls": ["/api/**"],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize": 100,
        "maxAge": "1h",
        "timeout": "10s"
      }
    }
  ]
}
  • API调用使用网络优先策略
json
{
  "dataGroups": [
    {
      "name": "api",
      "urls": ["/api/**"],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize": 50,
        "maxAge": "1h"
      }
    }
  ]
}
  • 静态资源使用缓存优先策略
json
{
  "assetGroups": [
    {
      "name": "static",
      "installMode": "prefetch",
      "updateMode": "prefetch",
      "resources": {
        "files": ["/*.js", "/*.css"]
      }
    }
  ]
}
  • 处理离线状态
ts
import { SwPush } from '@angular/service-worker';

constructor(private swPush: SwPush) {}

subscribeToNotifications() {
  if (this.swPush.isEnabled) {
    this.swPush.requestSubscription({
      serverPublicKey: 'VAPID_PUBLIC_KEY'
    });
  }
}
  • 检查service worker更新
ts
import { SwUpdate } from '@angular/service-worker';

constructor(private updates: SwUpdate) {
  this.updates.versionUpdates.subscribe(event => {
    if (event.type === 'VERSION_READY') {
      // Reload to get new version
      window.location.reload();
    }
  });
}
  • 自定义manifest
json
{
  "name": "My PWA",
  "short_name": "MyPWA",
  "theme_color": "#1976d2",
  "background_color": "#ffffff",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "icons": [
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ]
}