Introduction to Progressive Web Apps
Progressive Web Apps (PWAs) represent a modern approach to web application development that combines the best of web and mobile applications. They are web applications that leverage modern web capabilities to deliver an app-like experience to users.
What Makes an App "Progressive"?
The term "progressive" refers to the idea that these applications work for every user, regardless of browser choice, because they're built with progressive enhancement as a core principle. They progressively enhance the user experience based on the capabilities of the user's device and browser.
Real-world analogy: Think of PWAs like adaptable vehicles that can transform based on the road conditions. On smooth highways (modern browsers), they perform like high-end sports cars with all features enabled. On rough terrain (older browsers), they function more like rugged jeeps, losing some fancy features but still getting you to your destination.
Historical Context
The concept of PWAs was introduced by Google in 2015, with Alex Russell and Frances Berriman coining the term. They identified the patterns emerging in modern web applications and formalized them into the PWA concept.
Since then, PWAs have gained significant traction, with major companies like Twitter, Starbucks, Pinterest, Uber, and many others adopting this approach to deliver better user experiences while reducing development costs compared to maintaining separate web and native applications.
Core Principles of PWAs
Progressive Web Apps are built on three fundamental principles:
1. Reliability
PWAs should load instantly and never show the "dinosaur" offline page, even in uncertain network conditions.
- Functions offline or with poor connectivity
- Loads consistently regardless of network state
- Eliminates the dependency on continuous network connectivity
2. Performance
PWAs should respond quickly to user interactions with smooth animations and jank-free scrolling.
- Fast loading with minimal waiting time
- Smooth animations and transitions
- Responsive to user inputs without delays
- Efficient resource usage (battery, data, CPU)
3. Engagement
PWAs should feel like a natural app on the device, with an immersive user experience.
- Installable on home screen without app store
- Provides immersive full-screen experience
- Re-engages users with push notifications
- Feels integrated with the device
Technical Components of PWAs
PWAs are built using several key technologies that work together:
1. HTTPS
PWAs must be served over HTTPS to ensure security. This is a prerequisite for many PWA features like service workers and geolocation.
- Protects user data integrity and privacy
- Prevents content tampering
- Required for service worker registration
- Builds user trust
2. Web App Manifest
A JSON file that controls how the app appears when installed on a device:
- Defines app name, icons, and theme colors
- Specifies start URL and display mode
- Controls orientation and splash screen
// Example manifest.json
{
"name": "Weather PWA",
"short_name": "Weather",
"description": "Weather forecast information",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#3E4EB8",
"theme_color": "#2F3BA2",
"icons": [
{
"src": "/images/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "/images/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "/images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "/images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "/images/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "/images/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/images/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "/images/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
3. Service Workers
JavaScript files that run in the background, separate from the web page, enabling features like offline functionality and push notifications:
- Intercepts network requests
- Caches resources for offline use
- Enables background synchronization
- Handles push notifications
// Basic service worker registration
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('ServiceWorker registration successful with scope: ',
registration.scope);
})
.catch(error => {
console.log('ServiceWorker registration failed: ', error);
});
});
}
4. Application Shell Architecture
A design approach that separates the app's core infrastructure (shell) from its content:
- Loads the minimal UI immediately
- Caches shell for instant future loads
- Loads content dynamically
- Improves perceived performance
Key Capabilities and Features
Offline Functionality
PWAs can work even when the user has no internet connection or limited connectivity:
- Provides essential functionality without network access
- Caches previously accessed content for offline viewing
- Handles network failures gracefully with fallback content
- Synchronizes data when connectivity is restored
Real-world example: Google Maps PWA allows users to download and access maps offline, enabling navigation without continuous internet access. Similarly, Spotify's PWA caches music for offline listening.
Installability
PWAs can be added to a user's home screen, making them easily accessible:
- Appears as an icon on home screen like native apps
- Launches in standalone or full-screen mode without browser UI
- Shows up in app switcher/task manager
- No app store required for distribution
// Check if the app can be installed
window.addEventListener('beforeinstallprompt', (event) => {
// Prevent the default prompt
event.preventDefault();
// Store the event for later use
let deferredPrompt = event;
// Show your custom "Add to Home Screen" button
installButton.style.display = 'block';
installButton.addEventListener('click', () => {
// Show the install prompt
deferredPrompt.prompt();
// Wait for the user to respond
deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the install prompt');
} else {
console.log('User dismissed the install prompt');
}
// Clear the saved prompt
deferredPrompt = null;
// Hide the install button
installButton.style.display = 'none';
});
});
});
Push Notifications
PWAs can send notifications to users even when the browser is closed:
- Re-engages users with timely, relevant information
- Works across devices where the user is logged in
- Can function without the app being open
- Requires user permission
// Request notification permission
function requestNotificationPermission() {
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
// Subscribe the user to push notifications
subscribeToPushNotifications();
}
});
}
// Subscribe to push notifications
function subscribeToPushNotifications() {
navigator.serviceWorker.ready.then(registration => {
// Get the server's public key
return registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicKey)
});
})
.then(subscription => {
// Send the subscription to your server
return fetch('/api/subscriptions', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
});
})
.catch(error => {
console.error('Error subscribing to push notifications:', error);
});
}
Background Sync
PWAs can defer actions until the user has stable connectivity:
- Queues failed network requests for later execution
- Ensures data isn't lost due to temporary connectivity issues
- Improves reliability of critical operations
- Works even after the user has closed the application
// Register for background sync
navigator.serviceWorker.ready.then(registration => {
if ('sync' in registration) {
// Listen for form submissions
document.querySelector('form').addEventListener('submit', event => {
event.preventDefault();
// Get the form data
const formData = new FormData(event.target);
// Store the data in IndexedDB
saveFormDataToIndexedDB(formData)
.then(() => {
// Register a sync event
return registration.sync.register('submit-form');
})
.then(() => {
console.log('Background sync registered!');
// Show the user that the data will be submitted
showOfflineSubmissionConfirmation();
})
.catch(error => {
console.error('Error registering background sync:', error);
// Handle the error appropriately
});
});
}
});
App-like Interactions
PWAs offer smooth animations and responsive interactions:
- No page reloads during navigation
- Smooth transitions between pages
- Gesture support for intuitive interactions
- Persistent UI elements like native apps
Discoverability
PWAs are discoverable through search engines and can be shared via URLs:
- Indexed by search engines
- Sharable via links
- No app store submission process required
- Can be discovered naturally through web browsing
PWA Architecture Patterns
Application Shell Architecture
The app shell architecture separates the app's interface from its content:
// Example structure
|-- index.html # App shell HTML
|-- styles/
| |-- app-shell.css # Core UI styles
| |-- content.css # Content-specific styles
|-- scripts/
| |-- app-shell.js # Shell functionality
| |-- router.js # Client-side routing
| |-- api.js # API interactions
|-- images/
| |-- icons/ # App icons
|-- manifest.json # Web app manifest
|-- sw.js # Service worker
The shell typically includes:
- Header and navigation
- Sidebar or menu
- Footer
- Loading indicators
- Basic layout structure
Content is then loaded dynamically into this shell.
PRPL Pattern
PRPL is a pattern for structuring and serving Progressive Web Apps with an emphasis on performance:
- Push critical resources for the initial route
- Render initial route as quickly as possible
- Pre-cache remaining routes
- Lazy-load other routes and non-critical resources
SPA + API Architecture
Many PWAs follow a Single Page Application (SPA) architecture with an API backend:
- Frontend handles routing, UI rendering, and state management
- Backend API provides data and business logic
- Service workers cache both the app shell and API responses
- IndexedDB can be used for client-side data storage
PWA with Popular Frameworks
React PWA
React provides tools like Create React App that make building PWAs straightforward:
// Creating a React PWA
npx create-react-app my-pwa --template cra-template-pwa
Key components in a React PWA:
- Service worker registration in
index.js - Generated manifest.json
- Workbox for service worker management
- React Router for client-side routing
// Service worker registration in React
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://cra.link/PWA
serviceWorkerRegistration.register();
Angular PWA
Angular provides the @angular/pwa package that adds PWA support to an existing Angular project:
// Adding PWA support to an Angular project
ng add @angular/pwa
This automatically adds:
- A manifest.json file
- Service worker configuration
- Icons for different device sizes
- Updates to the app module to register the service worker
// Service worker registration in Angular
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production,
// Register the ServiceWorker as soon as the app is stable
// or after 30 seconds (whichever comes first).
registrationStrategy: 'registerWhenStable:30000'
})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Vue PWA
Vue CLI provides a PWA plugin that simplifies PWA creation:
// Creating a Vue PWA
vue create my-pwa
# Select the PWA feature during project creation
// Or add PWA to an existing Vue project
vue add pwa
The Vue PWA plugin provides:
- Service worker registration in
main.js - A manifest.json file in the public directory
- Configuration through
vue.config.js - Workbox integration for advanced service worker features
// Service worker registration in Vue
// src/registerServiceWorker.js
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log('App is being served from cache by a service worker.')
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('Content has been cached for offline use.')
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}
PWA Performance Optimization
Lighthouse Auditing
Lighthouse is a tool for improving the quality of web pages, including PWA features:
- Audits PWA compliance and best practices
- Measures performance metrics
- Checks accessibility
- Evaluates SEO
- Available in Chrome DevTools, as a CLI tool, or as a Node module
Critical Rendering Path Optimization
Optimizing the critical rendering path improves initial load performance:
- Inline critical CSS
- Defer non-critical JavaScript
- Optimize image loading with lazy loading
- Minimize main thread work
Caching Strategies
Different resources benefit from different caching strategies:
- Cache-first: Check cache, falling back to network (good for app shell)
- Network-first: Try network, falling back to cache (good for frequently updated content)
- Stale-while-revalidate: Serve from cache while updating cache in background (good for content that updates periodically)
- Cache-only: Serve only from cache (good for static assets)
- Network-only: Always use network (good for user-specific data)
Responsive Design Principles
PWAs should work well on all device sizes:
- Use responsive layouts with CSS Grid and Flexbox
- Implement responsive images with srcset and sizes
- Design for touch with appropriate hit targets
- Consider offline states in UI design
PWA Best Practices
Security Considerations
- Always serve over HTTPS
- Practice Content Security Policy (CSP) implementation
- Be cautious with the data stored in client-side storage
- Validate all data from service workers
- Keep service worker scope as restrictive as necessary
User Experience Guidelines
- Provide clear offline indicators
- Design for intermittent connectivity, not just online/offline states
- Implement splash screens for app-like feel
- Use "Add to Home Screen" prompts at appropriate moments
- Ensure accessibility for all users
Testing PWAs
- Test offline functionality regularly
- Test across different devices and screen sizes
- Test with slow network connections (throttling)
- Verify push notification behavior
- Check installation experience
- Run Lighthouse audits to ensure compliance
PWA Checklist
Google provides a comprehensive PWA checklist that includes:
- Site is served over HTTPS
- Pages are responsive on tablets & mobile devices
- All app URLs load while offline
- Metadata provided for Add to Home screen
- First load fast even on 3G
- Site works cross-browser
- Page transitions don't feel like they block on the network
- Each page has a URL
Meeting these criteria ensures your PWA provides a high-quality experience on all devices.
Real-World PWA Examples
Twitter Lite
Twitter Lite is a PWA that reduced data usage and load times:
- 30% faster launch time
- 65% increase in pages per session
- 75% increase in Tweets sent
- 20% decrease in bounce rate
Starbucks PWA
Starbucks built a PWA for their ordering system:
- Size reduced from 146MB (native app) to 233KB (PWA)
- Works offline to browse the menu and customize orders
- Allows ordering even with intermittent connectivity
- Desktop and mobile web ordering doubled daily active users
Pinterest PWA
Pinterest's PWA dramatically improved their mobile web experience:
- 40% increase in time spent
- 44% increase in user-generated ad revenue
- 60% increase in engagement
- Core engagements up 60%
Uber PWA
Uber's PWA (m.uber.com) loads quickly even on 2G networks:
- Loads in under 3 seconds on 2G connections
- Works on any browser
- Only 50KB gzipped
- Allows ride requests without installing the native app
Practice Activity
PWA Analysis
For this activity, you'll analyze an existing PWA to understand its architecture and capabilities:
- Choose one of the following PWAs to analyze:
- Twitter Lite (mobile.twitter.com)
- Spotify Web Player (open.spotify.com)
- Starbucks (app.starbucks.com)
- Pinterest (www.pinterest.com)
- Instagram Web (www.instagram.com)
- Using Chrome DevTools, analyze the PWA:
- Examine the manifest.json file (Application tab > Manifest)
- Look at the registered service worker (Application tab > Service Workers)
- Check the caching strategy (Application tab > Cache Storage)
- Run a Lighthouse audit (Lighthouse tab > Generate report)
- Document your findings:
- What capabilities does the PWA implement? (offline support, push notifications, etc.)
- How is the app shell structured?
- What caching strategies are used?
- How is the application optimized for performance?
- What could be improved based on the Lighthouse audit?
PWA Setup Exercise
In this exercise, you'll add the basic PWA capabilities to a web application:
- Create a new project using your preferred framework:
- React:
npx create-react-app my-pwa --template cra-template-pwa - Angular:
ng new my-pwathenng add @angular/pwa - Vue:
vue create my-pwa(select PWA option) - Or use a simple HTML/JS/CSS project
- React:
- Verify the manifest.json file has all required fields:
- name, short_name
- start_url
- display (standalone or fullscreen)
- background_color, theme_color
- icons in various sizes
- Ensure service worker registration is enabled
- Run a Lighthouse audit to check PWA compliance
- Make any necessary improvements based on the audit results
Key Takeaways
- Progressive Web Apps combine the best of web and mobile app experiences
- PWAs are built on three core principles: reliability, performance, and engagement
- Key technologies include HTTPS, Web App Manifest, and Service Workers
- PWAs offer capabilities like offline functionality, installability, and push notifications
- The App Shell Architecture separates UI structure from content for better performance
- Popular frameworks like React, Angular, and Vue provide tools for PWA development
- Performance optimization is critical for delivering a good PWA experience
- Real-world PWAs have demonstrated significant business benefits