Progressive Web Apps (PWAs)
Progressive Web Apps (PWAs) are web applications that use modern web capabilities to deliver an app-like experience to users. They are:
- Reliable - Load instantly and never show the “downasaur” (Chrome’s offline dinosaur) even in uncertain network conditions.
- Fast - Respond quickly to user interactions with silky smooth animations and no janky scrolling.
- Engaging - Feel like a natural app on the device, with an immersive user experience.
PWAs combine the best of web and native apps. They can work offline, send push notifications, and even be installed on the home screen, without the need for an app store.
Service Workers
Service workers are a key technology behind PWAs. They act as a proxy between the web app and the network, allowing you to control how network requests are handled.
To add a service worker to your Angular app:
- Use the Angular CLI to add PWA support:
ng add @angular/pwa
This command will:
- Add the
@angular/service-worker
package - Enable service worker build support in the CLI
- Import and register the service worker in the app module
- Update the
index.html
file - Create a configuration file
ngsw-config.json
- Create app icons in
src/assets/icons
- The
ngsw-config.json
file configures the service worker. Here’s a basic example:
{
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.webmanifest",
"/*.css",
"/*.js"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
]
}
}
]
}
This configuration tells the service worker to prefetch and cache the app’s core files and lazy-load other assets.
App Manifests
The Web App Manifest is a JSON file that provides information about your web application. It tells the browser how your app should behave when installed on the user’s desktop or mobile device.
When you add PWA support to your Angular app, a manifest.webmanifest
file is automatically created in the src
folder. Here’s an example:
{
"name": "My Angular PWA",
"short_name": "AngularPWA",
"theme_color": "#1976d2",
"background_color": "#fafafa",
"display": "standalone",
"scope": "./",
"start_url": "./",
"icons": [
{
"src": "assets/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable any"
},
// ... other icon sizes ...
]
}
You can customize this file to change how your app appears when installed.
Offline Capabilities
PWAs can work offline or in low-quality network conditions. Here’s how to implement offline capabilities:
-
Cache static assets: The
ngsw-config.json
file already configures caching for your app’s static assets. -
Handle dynamic data: For dynamic data, you can use strategies like “Cache then network” or “Network then cache”. Implement these in your services:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
private cache: any = {};
constructor(private http: HttpClient) {}
getData(url: string): Observable<any> {
// Check cache first
if (this.cache[url]) {
return of(this.cache[url]);
}
// If not in cache, fetch from network
return this.http.get(url).pipe(
tap(response => {
// Save response in cache
this.cache[url] = response;
}),
catchError(error => {
console.error('Error fetching data', error);
// If offline, return cached data if available
return this.cache[url] ? of(this.cache[url]) : of(null);
})
);
}
}
- Handle offline state:
Use the
Online/Offline
events to detect network status:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div *ngIf="!isOnline">You are currently offline</div>
<!-- rest of your app -->
`
})
export class AppComponent implements OnInit {
isOnline: boolean = navigator.onLine;
ngOnInit() {
window.addEventListener('online', this.updateOnlineStatus.bind(this));
window.addEventListener('offline', this.updateOnlineStatus.bind(this));
}
updateOnlineStatus() {
this.isOnline = navigator.onLine;
}
}
- Testing offline functionality:
- Use Chrome DevTools: Go to the Network tab and check the “Offline” box.
- Use Lighthouse in Chrome DevTools to audit your PWA.
By following these steps, you’ll have created a basic PWA with Angular that works offline, can be installed on devices, and provides a native app-like experience.
Remember to thoroughly test your PWA in various network conditions and on different devices to ensure a smooth user experience.