PWA 由哪些部分组成?怎样把传统网站改造成可安装、可离线的应用?
先理解原理和示例,再练习完整口述与追问。
回答要点
核心是 HTTPS、Web App Manifest 和 Service Worker。Manifest 描述名称、图标、启动地址和显示方式;Service Worker 拦截请求,实现离线缓存、后台同步和推送。改造时为不同资源选择缓存策略,设计更新提示,避免旧缓存困住用户。
原理拆解
Manifest 通过 <link rel="manifest"> 引入,display: standalone 让应用从主屏打开时没有地址栏。Service Worker 运行在独立线程,只能在安全上下文注册,作用域由注册路径决定;它的 fetch 事件可以返回缓存或网络响应。各浏览器的“可安装”条件不同,以目标浏览器文档为准;iOS 16.4 起,添加到主屏的 Web 应用支持 Web Push。
缓存策略:带哈希的静态资源用缓存优先,HTML 和接口数据用网络优先并以缓存兜底,头像等可容忍旧数据的资源用 stale-while-revalidate。新版本 Service Worker 安装后会进入 waiting 状态,直到旧页面全部关闭;可以提示用户刷新,确认后调用 skipWaiting。
示例与推演
self.addEventListener('fetch', event => {
const { request } = event
if (request.mode === 'navigate') {
event.respondWith(fetch(request).catch(() => caches.match('/offline.html')))
} else if (request.url.includes('/assets/')) {
event.respondWith(caches.match(request).then(hit => hit || fetch(request)))
}
})
导航请求在网络失败时返回离线页,带哈希的资源走缓存优先。工程中常用 Workbox 或 vite-plugin-pwa 生成预缓存清单。
易错点
把 index.html 也用缓存优先,会导致用户长期停留在旧版本;缓存需要登录的接口响应,可能在共享设备上泄露数据,退出登录时要清理。
参考回答可直接练习口述
PWA 的基础是 HTTPS、Manifest 和 Service Worker。Manifest 让网站有名称、图标和独立窗口,Service Worker 拦截请求实现离线缓存,也能做推送和后台同步。改造时我会按资源类型选择策略:带哈希的静态资源缓存优先,页面和接口网络优先、离线兜底;新版本 Service Worker 进入 waiting 后提示用户刷新。还要避免缓存 HTML 过久和缓存敏感接口数据。