渐进式 Web 应用(PWA)实现指南:将网站变成可安装的 App
PWA(Progressive Web App)让网站拥有原生应用的体验:可安装到主屏幕、离线运行、推送通知。
PWA 核心组件
PWA 由三个核心组件构成:
第一步:配置 Manifest
{
"name": "16IDC",
"short_name": "16IDC",
"description": "Cloud service comparison and website building guide",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#4F46E5",
"icons": [
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
在 HTML 中引用 Manifest:
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#4F46E5">
第二步:注册 Service Worker
// main.js
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
const registration = await navigator.serviceWorker.register('/sw.js');
console.log('ServiceWorker registered:', registration.scope);
} catch (error) {
console.log('ServiceWorker registration failed:', error);
}
});
}
第三步:Service Worker 缓存策略
// sw.js
const CACHE_NAME = 'v1';
const STATIC_ASSETS = [
'/',
'/styles.css',
'/app.js',
'/offline.html'
];
// 安装:预缓存静态资源
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(STATIC_ASSETS))
.then(() => self.skipWaiting())
);
});
// 激活:清理旧缓存
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(keys.map(key => {
if (key !== CACHE_NAME) return caches.delete(key);
}))
).then(() => self.clients.claim())
);
});
// 拦截请求:缓存优先策略
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(cached => cached || fetch(event.request))
.catch(() => caches.match('/offline.html'))
);
});
缓存策略选择
| 策略 | 说明 | 适用场景 |
|---|---|---|
| Cache First | 优先使用缓存,无缓存时才请求网络 | 静态资源(CSS、JS、图片) |
| Network First | 优先请求网络,失败时使用缓存 | API 请求、动态页面 |
| Stale While Revalidate | 返回缓存,同时后台更新 | 不经常变化的内容 |
| Network Only | 始终请求网络 | 支付、表单提交 |
| Cache Only | 仅使用缓存 | 离线页面 |
离线页面
创建 offline.html,当用户离线访问时显示友好的提示:
<!DOCTYPE html>
<html>
<head>
<title>您处于离线状态</title>
<style>
body { text-align: center; padding: 50px; font-family: system-ui; }
</style>
</head>
<body>
<h1>暂无网络连接</h1>
<p>请检查您的网络连接后重试</p>
</body>
</html>
PWA 检测工具
- Lighthouse — Chrome DevTools 内置的 PWA 审计
- PWABuilder — Microsoft 的 PWA 打包工具
- PWA Checker — 在线 PWA 合规性检测
16IDC 观察
PWA 是提升网站用户体验性价比最高的方案之一。实现成本低(只需一个 Manifest 文件和一个 Service Worker),但可以显著提升用户参与度。建议所有内容型网站和工具型网站都考虑实现 PWA。