LEARNING OBJECTIVES ⌵
- Master the official Chromium PWA Installability Checklist and pass 100% of Lighthouse PWA audit criteria.
- Validate Web App Manifest properties, maskable icon safe zones, and start URLs in the Chrome DevTools Application Panel.
- Test offline capability, network throttling, and Service Worker updates under simulated Slow 3G / Lie-Fi conditions.
- Automate PWA quality gates using Lighthouse CLI (
@lhci/cli) in continuous integration pipelines.
📖 The Mental Model & Story (Intuitive Foundation)
Imagine manufacturing an automobile intended for high-speed highways. Before the car can be licensed and sold to the public, it must pass a rigorous multi-point vehicle inspection: the brakes must stop within a measured distance, the airbags must deploy on impact, the headlights must illuminate dark roads, and the frame must survive crash simulations. If even a single taillight wire is broken, the vehicle fails inspection.
Google Lighthouse and Browser DevTools are the automotive testing laboratory for Progressive Web Apps.
You cannot simply assume your Service Worker caches properly or that your manifest icon won't be mutilated by a Samsung phone's squircle mask. Lighthouse executes an automated battery of simulated network dropouts, HTTPS handshakes, responsive viewport resizes, and manifest parsers to give you a definitive mathematical score (0–100%) and a binary pass/fail verification of your app's installability and resilience.
Technical Deep Dive & Specifications
The Lighthouse PWA Audit Matrix
Lighthouse evaluates your application against three distinct categories of progressive web standards:
+---------------------------------------------------------------------------------------+
| LIGHTHOUSE PWA AUDIT SUITE |
+---------------------------------------------------------------------------------------+
| | |
| [ 1. INSTALLABLE CRITERIA ] | [ 2. PWA OPTIMIZED CRITERIA ] |
| - Web App Manifest is valid | - Redirects HTTP traffic to HTTPS |
| - Contains 'name' or 'short_name' | - Configured with custom splash screen |
| - Sets 'start_url' within scope | - Sets themed address bar (theme_color) |
| - Sets 'display': standalone/fullscreen | - Content is sized correctly for viewport|
| - Provides icons >= 192px and >= 512px | - Provides a valid apple-touch-icon |
| - Provides a valid maskable icon | - Maskable icon satisfies safe-zone rules|
| - Registers an active Service Worker | - Fast First Contentful Paint (<1.8s) |
| - Responds with 200 OK when OFFLINE | |
+---------------------------------------------------------------------------------------+
DevTools PWA Inspection Workflow
+-----------------------------------------+
| CHROME DEVTOOLS > APPLICATION PANEL |
+-----------------------------------------+
|
+-------------------------------+-------------------------------+
| | |
v v v
+-------------------------+ +-------------------------+ +-------------------------+
| [ MANIFEST ] | | [ SERVICE WORKERS ] | | [ CACHE STORAGE ] |
| - Identity (name, id) | | - Status: Activated | | - Inspect cache buckets |
| - Start URL & Scope | | - Checkbox: "Offline" | | - Verify precached HTML |
| - Maskable Safe Zone: | | - Checkbox: "Update on | | - Inspect headers & MIME|
| "Show only minimum | | reload" | | - Delete stale entries |
| safe area" toggle | | - Trigger Push / Sync | | |
+-------------------------+ +-------------------------+ +-------------------------+
Automated Audits via Lighthouse CI (lighthouserc.json)
To prevent regressions in production, top frontend teams run Lighthouse in GitHub Actions or GitLab CI on every pull request:
{
"ci": {
"collect": {
"numberOfRuns": 3,
"startServerCommand": "npm run start",
"url": ["http://localhost:8080/"]
},
"assert": {
"assertions": {
"categories:pwa": ["error", { "minScore": 1.0 }],
"service-worker": "error",
"installable-manifest": "error",
"splash-screen": "error",
"themed-omnibox": "error",
"content-width": "error",
"apple-touch-icon": "error",
"maskable-icon": "error"
}
}
}
}
💻 Interactive Code Playground
Starter Code: 100% Lighthouse Compliant PWA Boilerplate
Below is the complete HTML document and metadata bundle that satisfies 100% of Lighthouse and Chromium installability requirements.
1. File: index.html
2. File: manifest.webmanifest
3. File: sw.js
Line-by-Line Code Breakdown
index.htmlLine 5 (<meta name="viewport" ...>): Eliminates the 300ms mobile tap delay and ensures responsive layout rendering.index.htmlLine 15 (<link rel="apple-touch-icon" ...>): Provides iOS WebKit with a non-transparent 180x180 PNG icon when saving to the iOS home screen.manifest.webmanifestLine 17–28 ("purpose": "any"&"purpose": "maskable"): Satisfies the dual-icon requirement: rectangular display for desktop and squircle-masked display for Android.sw.jsLine 28 (catch(() => caches.match('/index.html'))): Satisfies the Lighthouse requirement: "Current page responds with a 200 when offline".
Expected Browser Render Output
{
"id": "/?app=lighthouse_audit_pwa",
"name": "Lighthouse Verified PWA",
"short_name": "AuditPWA",
"description": "Production Progressive Web App passing all automated audits.",
"start_url": "/index.html",
"scope": "/",
"display": "standalone",
"orientation": "portrait-primary",
"background_color": "#0f172a",
"theme_color": "#2563eb",
"categories": ["productivity", "utilities"],
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}const CACHE_NAME = 'lighthouse-audit-cache-v1';
const ASSETS = [
'/',
'/index.html',
'/manifest.webmanifest',
'/icons/icon-192.png',
'/icons/icon-512.png',
'/icons/icon-maskable-512.png',
'/icons/apple-touch-icon.png'
];
self.addEventListener('install', (e) => {
e.waitUntil(
caches.open(CACHE_NAME).then((cache) => cache.addAll(ASSETS))
);
self.skipWaiting();
});
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then((keys) => {
return Promise.all(
keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k))
);
}).then(() => self.clients.claim())
);
});
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request).then((cached) => {
return cached || fetch(e.request).catch(() => caches.match('/index.html'));
})
);
});(Running Google Chrome Lighthouse Audit):
+--------------------------------------------------------------------+
| LIGHTHOUSE AUDIT REPORT |
| |
| [ 100 ] Progressive Web App (PWA) |
| |
| Passed Audits (12): |
| [✓] Web App Manifest meets installability requirements |
| [✓] Service Worker is registered and active |
| [✓] Responds with a 200 when offline |
| [✓] Configured for a custom splash screen |
| [✓] Sets an address bar theme color |
| [✓] Content is sized correctly for the viewport |
| [✓] Provides a valid apple-touch-icon |
| [✓] Manifest has a maskable icon with safe zone margins |
| [✓] Uses HTTPS |
| [✓] Redirects HTTP to HTTPS |
+--------------------------------------------------------------------+🏋️ Hands-On Exercise
🎯 The Challenge: Diagnose and Fix a Broken PWA Audit
Instructions:
- Review the broken starter codebase below.
- Identify 3 fatal errors causing Lighthouse to fail the PWA installability test.
- Correct the HTML and JSON manifest so it achieves a full pass.
🏁 Starter Code Sandbox (Contains 3 Intentional Bugs)
⚠️ Common Pitfalls
- Testing Only on Fast Fiber Wi-Fi: A PWA that loads in 200ms on a desktop MacBook can fail Lighthouse's mobile audit because Lighthouse simulates a 4x CPU throttle and a Slow 4G mobile network. Always optimize your JS bundle size.
- Forgetting the
apple-touch-icon: iOS Safari ignores the icons insidemanifest.webmanifest. If you do not include<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">in the HTML<head>, iOS home screen icons will be a tiny screenshot of your webpage. - Failing the Offline 200 Status Test: If your Service Worker catches offline fetch errors but returns a custom Response with
status: 503or408, Lighthouse will fail the audit. The navigation fallback must returnstatus: 200.
💡 Pro Tips
- Use Chrome DevTools "Show only minimum safe area" for Maskable Icons: In DevTools > Application > Manifest, click the maskable icon checkbox to visualize how Android circular and squircle masks crop your icon, verifying that no text or logo crosses the 40% radius safe line.
- Integrate Lighthouse CI into GitHub Actions: Set up
.github/workflows/lighthouse.ymlwith@lhci/clito automatically fail pull requests if a code change drops the PWA score below 100.
📌 Key Takeaways
- Google Lighthouse provides standardized, automated verification of PWA installability, security, and performance.
- 100% PWA compliance requires a valid manifest,
standalonedisplay, 192px/512px maskable icons, HTTPS, and an active Service Worker. - The Service Worker must return a 200 OK response when offline for root navigation requests.
- iOS WebKit requires an explicit
<link rel="apple-touch-icon">tag in HTML<head>. - The Chrome DevTools Application Panel enables live inspection of manifest schemas, maskable safe zones, and cache storage buckets.
- --