PWA 解决什么问题

网页的天生短板是"没网就打不开、加载慢就白屏、用完即走不像 App"。PWA(渐进式 Web 应用)用一组现代浏览器技术,让网页具备离线可访问、加载快、能添加到主屏、像原生 App 一样有图标和启动画面的能力,同时保留网页免安装、易分享的优势。它不是新框架,而是 Service Worker、缓存、Manifest 这些能力的组合拳。

PWA 的核心价值:让网页在弱网和离线环境下依然立得住,而不是一断网就白屏。
本文核心知识点
  • Service Worker独立于页面的后台代理,拦截请求、管缓存。
  • 缓存策略不同资源用不同策略,兼顾新鲜与速度。
  • Manifest描述应用名、图标、启动方式,可安装到主屏。
  • 离线能力断网时用缓存兜底,后台同步补数据。
PWA 离线应用配图:蓝色渐变背景上浏览器窗口内嵌发光盾牌对勾,旁边 wifi 波纹与排队的数据方块
盾牌代表离线兜底,wifi 波纹代表联网更新,数据方块队列代表后台同步——PWA 的三要素。

Service Worker:网页的离线代理

Service Worker 是一段在浏览器后台独立运行的脚本,与网页解耦:页面关了它还能跑,能拦截页面发出的网络请求、决定是走网络还是读缓存。注册它之后,浏览器每次请求资源,都要先经过这个代理。

// 在页面里注册 Service Worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}

// sw.js:拦截请求,先读缓存,缓存没有再走网络
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((cached) => {
      return cached || fetch(event.request);
    })
  );
});

注意它只能跑在 HTTPS 或 localhost 下,且首次注册后需要刷新一次页面才生效。

缓存策略:stale-while-revalidate

缓存不是"存起来就完了",不同资源要配不同策略。静态资源(JS/CSS/图片)内容变了就换文件名,适合"缓存优先",下次秒开。HTML 这类要及时更新的,用 stale-while-revalidate:先用缓存让页面立刻显示,同时在后台悄悄拉最新版本存起来,下次打开就是新的。

// HTML 用 stale-while-revalidate:先缓存、后台更新
self.addEventListener('fetch', (event) => {
  if (event.request.destination === 'document') {
    event.respondWith(
      caches.open('pages').then(async (cache) => {
        const cached = await cache.match(event.request);
        const fetchPromise = fetch(event.request).then((res) => {
          cache.put(event.request, res.clone());
          return res;
        });
        return cached || fetchPromise;   // 有缓存先用,没缓存等网络
      })
    );
  }
});

Web App Manifest:添加到主屏

要让网页能"像 App 一样安装到主屏",需要一个 manifest.json 描述应用名、图标、启动方式、主题色。浏览器满足条件后就会提示用户"安装应用",安装后从主屏图标启动,还能隐藏浏览器边框全屏运行。

{
  "name": "吉极云码",
  "short_name": "吉极云码",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#1E5FA8",
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192" },
    { "src": "/icon-512.png", "sizes": "512x512" }
  ]
}

离线与后台同步

PWA 更进一步的能力是离线也能操作、联网后自动同步。用户在地铁里断网时浏览页面、甚至提交表单,先把操作存在 IndexedDB 里;等网络恢复,Service Worker 的后台同步(Background Sync)事件自动把离线期间攒的请求补发出去,用户全程无感。这让网页在弱网场景下的体验大幅接近原生 App。