瀏覽器遊戲的最大限制:使用者每次都要打開瀏覽器、輸入網址。PWA(Progressive Web App)解決這個問題 — 加 2 個檔案就能讓網站變成可加到桌面的 app,有 icon、可離線、跟原生 app 體驗極接近。這篇講工作室怎麼把遊戲大廳變成 PWA。
PWA 三件套
manifest.json:app metadata(名稱、icon、主題色)service-worker.js:背景 script(離線快取、推播)- HTTPS 部署:所有 PWA 必要條件
manifest.json
{
"name": "Hao0321 遊戲大廳",
"short_name": "Hao0321",
"description": "14 款原創瀏覽器遊戲,無需註冊。",
"start_url": "/",
"display": "standalone",
"orientation": "portrait",
"background_color": "#F4F4F7",
"theme_color": "#4A7BF5",
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
關鍵欄位:
display: "standalone":開啟時看不到瀏覽器 UI(網址列、書籤)theme_color:頂部狀態列顏色(Android)icon purpose: "maskable":iOS / Android 各自有不同的 icon 形狀,maskable 確保任何裁切下都漂亮
HTML 引用
<link rel="manifest" href="/manifest.json"> <meta name="theme-color" content="#4A7BF5"> <link rel="apple-touch-icon" href="/icons/icon-192.png">
service-worker.js — 快取核心檔案
const CACHE = 'hao0321-v1';
const ASSETS = [
'/',
'/play.html',
'/dodge-master-v5.html',
'/styles.css',
'/app.js',
'/icons/icon-192.png',
];
self.addEventListener('install', (e) => {
e.waitUntil(
caches.open(CACHE).then((cache) => cache.addAll(ASSETS))
);
});
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then((keys) =>
Promise.all(keys.filter(k => k !== CACHE).map(k => caches.delete(k)))
)
);
});
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request).then((cached) =>
cached || fetch(e.request).then((res) => {
// 同時更新 cache
return caches.open(CACHE).then((cache) => {
if (res.ok) cache.put(e.request, res.clone());
return res;
});
})
)
);
});
註冊 service worker
// 主頁面 JS
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then((reg) => console.log('SW registered:', reg.scope))
.catch((err) => console.error('SW error:', err));
});
}
離線體驗設計
PWA 的「離線」不是只 cache 檔案。要設計:
- 離線時哪些功能可以用?單機遊戲全部可以;排行榜需要顯示 cached 版本 + 提示「離線中」
- 離線提示:監聽
online/offline事件 - Queue 寫入:分數提交在離線時放進 IndexedDB queue,online 時補送
window.addEventListener('offline', () => {
showBanner('目前離線,分數會在恢復連線時上傳');
});
window.addEventListener('online', () => {
hideBanner();
flushScoreQueue();
});
「Add to Home Screen」提示
使用者用 Chrome 瀏覽多次後,瀏覽器會自動跳「加到主畫面」。也可以主動觸發:
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
document.getElementById('installBtn').style.display = 'block';
});
document.getElementById('installBtn').addEventListener('click', () => {
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choice) => {
console.log(choice.outcome); // 'accepted' or 'dismissed'
deferredPrompt = null;
});
});
iOS 的特殊處理
iOS Safari 對 PWA 支援不完整:
- 沒有
beforeinstallprompt事件,要使用者手動「分享 → 加到主畫面」 - service worker 在 iOS 14+ 才支援,舊版完全離線不可用
- standalone 模式下開啟外部連結會跳出 Safari,要用
target="_self"
更新策略
PWA 最頭痛的是「使用者裝舊版本」。解法:
// service-worker.js 加版本號 const CACHE = 'hao0321-v3'; // 改版時更新
新版本 install 後通知使用者:
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (confirm('新版本可用,要重新整理嗎?')) {
window.location.reload();
}
});
Lighthouse PWA 分數
Lighthouse 跑 PWA tab 會給分。要拿滿分需要:
- HTTPS
- manifest 完整(name, short_name, icons, theme_color, background_color, start_url, display)
- service worker 註冊成功
- 有 maskable icon
- 離線時可載入
結語
PWA 是被低估的「免費 app store 替代」。對獨立工作室是巨大的賦能 — 不用 App Store / Play Store 審核、不用 30% 抽成、不用懂 Swift / Kotlin。本工作室遊戲大廳變成 PWA 後,回流率(重複玩家)提升 25%。