Last updated
PWA Checklist Summary
- HTTPS: Required for service workers, push notifications, and camera/location APIs
- Service Worker: Enables offline functionality, background sync, and push notifications
- Web App Manifest: Enables installation, controls app appearance when installed
- Responsive Design: Works on all screen sizes and orientations
- Fast Loading: LCP under 2.5s, good Core Web Vitals scores
- Offline Experience: Meaningful content available without network connection
- Installable: Meets Chrome's installability criteria for Add to Home Screen
- Accessible: Meets WCAG 2.1 AA standards for all users
Examples
Example 1: Service Worker Registration
// Register service worker in your main JavaScript file:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('SW registered:', registration.scope);
})
.catch(error => {
console.error('SW registration failed:', error);
});
});
}
// sw.js — basic service worker with caching:
const CACHE_NAME = 'my-pwa-v1';
const CRITICAL_ASSETS = [
'/',
'/index.html',
'/css/main.css',
'/js/app.js',
'/offline.html'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(CRITICAL_ASSETS))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
.catch(() => caches.match('/offline.html'))
);
});
Example 2: Web App Manifest
// manifest.json — required for installability:
{
"name": "My Progressive Web App",
"short_name": "MyPWA",
"description": "A fast, reliable PWA",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0077BB",
"orientation": "portrait-primary",
"icons": [
{ "src": "/icons/icon-72.png", "sizes": "72x72", "type": "image/png" },
{ "src": "/icons/icon-96.png", "sizes": "96x96", "type": "image/png" },
{ "src": "/icons/icon-128.png", "sizes": "128x128", "type": "image/png" },
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
],
"screenshots": [
{ "src": "/screenshots/home.png", "sizes": "1280x720", "type": "image/png" }
]
}
<!-- Link manifest in HTML head: -->
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#0077BB" />
Example 3: Core Web Vitals Targets
PWA Performance Requirements:
Largest Contentful Paint (LCP):
✓ Good: ≤ 2.5 seconds
⚠ Needs improvement: 2.5–4.0 seconds
✗ Poor: > 4.0 seconds
First Input Delay (FID) / INP:
✓ Good: ≤ 200ms
⚠ Needs improvement: 200–500ms
✗ Poor: > 500ms
Cumulative Layout Shift (CLS):
✓ Good: ≤ 0.1
⚠ Needs improvement: 0.1–0.25
✗ Poor: > 0.25
Measure with:
- Chrome DevTools Lighthouse
- PageSpeed Insights
- Chrome User Experience Report (CrUX)