Service workers augment the traditional web deployment model and empower applications to deliver a user experience with the reliability and performance on par with natively-installed code. Adding a service worker to an Angular application is one of the steps for turning an application into a Progressive Web App (also known as a PWA).
At its simplest, a service worker is a script that runs in the web browser and manages caching for an application.
Service workers function as a network proxy. They intercept all outgoing HTTP requests made by the application and can choose how to respond to them. For example, they can query a local cache and deliver a cached response if one is available. Proxying isn’t limited to requests made through programmatic APIs, such as fetch
; it also includes resources referenced in HTML and even the initial request to index.html
. Service worker-based caching is thus completely programmable and doesn’t rely on server-specified caching headers.
Unlike the other scripts that make up an application, such as the Angular app bundle, the service worker is preserved after the user closes the tab. The next time that browser loads the application, the service worker loads first, and can intercept every request for resources to load the application. If the service worker is designed to do so, it can completely satisfy the loading of the application, without the need for the network.
Even across a fast reliable network, round-trip delays can introduce significant latency when loading the application. Using a service worker to reduce dependency on the network can significantly improve the user experience.
Angular applications, as single-page applications, are in a prime position to benefit from the advantages of service workers. Starting with version 5.0.0, Angular ships with a service worker implementation. Angular developers can take advantage of this service worker and benefit from the increased reliability and performance it provides, without needing to code against low-level APIs.
Angular’s service worker is designed to optimize the end user experience of using an application over a slow or unreliable network connection, while also minimizing the risks of serving outdated content.
The Angular service worker’s behavior follows that design goal:
To support these behaviors, the Angular service worker loads a manifest file from the server. The manifest describes the resources to cache and includes hashes of every file’s contents. When an update to the application is deployed, the contents of the manifest change, informing the service worker that a new version of the application should be downloaded and cached. This manifest is generated from a CLI-generated configuration file called ngsw-config.json
.
Installing the Angular service worker is as simple as including an [NgModule](https://angular.io/api/core/NgModule)
. In addition to registering the Angular service worker with the browser, this also makes a few services available for injection which interact with the service worker and can be used to control it. For example, an application can ask to be notified when a new update becomes available, or an application can ask the service worker to check the server for available updates.
To make use of all the features of Angular service worker, use the latest versions of Angular and the Angular CLI.
In order for service workers to be registered, the app must be accessed over HTTPS, not HTTP. Browsers ignore service workers on pages that are served over an insecure connection. The reason is that service workers are quite powerful, so extra care needs to be taken to ensure the service worker script has not been tampered with.
There is one exception to this rule: to make local development easier, browsers do not require a secure connection when accessing an app on localhost
.
To benefit from the Angular service worker, your app must run in a web browser that supports service workers in general. Currently, service workers are supported in the latest versions of Chrome, Firefox, Edge, Safari, Opera, UC Browser (Android version) and Samsung Internet. Browsers like IE and Opera Mini do not support service workers.
If the user is accessing your app via a browser that does not support service workers, the service worker is not registered and related behavior such as offline cache management and push notifications does not happen. More specifically:
ngsw.json
manifest file.[SwUpdate.checkForUpdate()](https://angular.io/api/service-worker/SwUpdate#checkForUpdate)
, return rejected promises.[SwUpdate.available](https://angular.io/api/service-worker/SwUpdate#available)
, are not triggered.It is highly recommended that you ensure that your app works even without service worker support in the browser. Although an unsupported browser ignores service worker caching, it will still report errors if the app attempts to interact with the service worker. For example, calling [SwUpdate.checkForUpdate()](https://angular.io/api/service-worker/SwUpdate#checkForUpdate)
will return rejected promises. To avoid such an error, you can check whether the Angular service worker is enabled using [SwUpdate.isEnabled](https://angular.io/api/service-worker/SwUpdate#isEnabled)()
.
This document explains how to enable Angular service worker support in projects that you created with the Angular CLI. It then uses a simple example to show you a service worker in action, demonstrating loading and basic caching.
To set up the Angular service worker in your project, use the CLI command ng add @angular/pwa
. It takes care of configuring your app to use service workers by adding the service-worker
package along with setting up the necessary support files.
ng add @angular/pwa --project *project-name*
The above command completes the following actions:
@angular/service-worker
package to your project.index.html
file:manifest.json
file.theme-color
.[ngsw-config.json](https://angular.io/guide/service-worker-config)
, which specifies the caching behaviors and other settings.Now, build the project:
ng build --prod
The CLI project is now set up to use the Angular service worker.
This section demonstrates a service worker in action, using an example application.
http-server
Because ng serve
does not work with service workers, you must use a separate HTTP server to test your project locally. You can use any HTTP server. The example below uses the http-server package from npm. To reduce the possibility of conflicts and avoid serving stale content, test on a dedicated port and disable caching.
To serve the directory containing your web files with http-server
, run the following command:
http-server -p 8080 -c-1 dist/<project-name>
With the server running, you can point your browser at http://localhost:8080/. Your application should load normally.
Tip: When testing Angular service workers, it’s a good idea to use an incognito or private window in your browser to ensure the service worker doesn’t end up reading from a previous leftover state, which can cause unexpected behavior.
Note: If you are not using HTTPS, the service worker will only be registered when accessing the app on localhost
.
To simulate a network issue, disable network interaction for your application. In Chrome:
Now the app has no access to network interaction.
For applications that do not use the Angular service worker, refreshing now would display Chrome’s Internet disconnected page that says “There is no Internet connection”.
With the addition of an Angular service worker, the application behavior changes. On a refresh, the page loads normally.
If you look at the Network tab, you can verify that the service worker is active.
Notice that under the “Size” column, the requests state is (from ServiceWorker)
. This means that the resources are not being loaded from the network. Instead, they are being loaded from the service worker’s cache.
Notice that all of the files the browser needs to render this application are cached. The ngsw-config.json
boilerplate configuration is set up to cache the specific resources used by the CLI:
index.html
.favicon.ico
.assets
.outputPath
(by default ./dist/<project-name>/
) or resourcesOutputPath
. See [ng build](https://angular.io/cli/build)
for more information about these options.Pay attention to two key points:
ngsw-config.json
includes a limited list of cachable fonts and images extentions. In some cases, you might want to modify the glob pattern to suit your needs.resourcesOutputPath
or assets
paths are modified after the generation of configuration file, you need to change the paths manually in ngsw-config.json
.Now that you’ve seen how service workers cache your application, the next step is understanding how updates work.
http-server
.src/app/app.component.html
for editing.Welcome to {{title}}!
to Bienvenue à {{title}}!
.ng build --prod
http-server -p 8080 -c-1 dist/<project-name>
Now look at how the browser and service worker handle the updated application.
What went wrong? Nothing, actually. The Angular service worker is doing its job and serving the version of the application that it has installed, even though there is an update available. In the interest of speed, the service worker doesn’t wait to check for updates before it serves the application that it has cached.
If you look at the http-server
logs, you can see the service worker requesting /ngsw.json
. This is how the service worker checks for updates.
The service worker installed the updated version of your app in the background, and the next time the page is loaded or reloaded, the service worker switches to the latest version.
App shell is a way to render a portion of your application via a route at build time. It can improve the user experience by quickly launching a static rendered page (a skeleton common to all pages) while the browser downloads the full client version and switches to it automatically after the code loads.
This gives users a meaningful first paint of your application that appears quickly because the browser can simply render the HTML and CSS without the need to initialize any JavaScript.
You can do this with the following CLI command:
ng new my-app --routing
For an existing application, you have to manually add the [RouterModule](https://angular.io/api/router/RouterModule)
and defining a <[router-outlet](https://angular.io/api/router/RouterOutlet)>
within your application.
Use the CLI to automatically create the app shell.
ng generate app-shell
client-project
takes the name of your client application.After running this command you will notice that the angular.json
configuration file has been updated to add two new targets, with a few other changes.
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/my-app-server",
"main": "src/main.server.ts",
"tsConfig": "tsconfig.server.json"
}
},
"app-shell": {
"builder": "@angular-devkit/build-angular:app-shell",
"options": {
"browserTarget": "my-app:build",
"serverTarget": "my-app:server",
"route": "shell"
},
"configurations": {
"production": {
"browserTarget": "my-app:build:production",
"serverTarget": "my-app:server:production"
}
}
}
Use the CLI to build the app-shell
target.
ng run my-app:app-shell
Or to use the production configuration.
ng run my-app:app-shell:production
To verify the build output, open dist/my-app/index.html
. Look for default text app-shell works!
to show that the app shell route was rendered as part of the output.
Importing [ServiceWorkerModule](https://angular.io/api/service-worker/ServiceWorkerModule)
into your AppModule
doesn’t just register the service worker, it also provides a few services you can use to interact with the service worker and control the caching of your app.
SwUpdate
serviceThe SwUpdate
service gives you access to events that indicate when the service worker has discovered an available update for your app or when it has activated such an update—meaning it is now serving content from that update to your app.
The [SwUpdate](https://angular.io/api/service-worker/SwUpdate)
service supports four separate operations:
The two update events, available
and activated
, are Observable
properties of [SwUpdate](https://angular.io/api/service-worker/SwUpdate)
:
log-update.service.ts
@Injectable()
export class LogUpdateService {
constructor(updates: SwUpdate) {
updates.available.subscribe(event => {
console.log('current version is', event.current);
console.log('available version is', event.available);
});
updates.activated.subscribe(event => {
console.log('old version was', event.previous);
console.log('new version is', event.current);
});
}
}
You can use these events to notify the user of a pending update or to refresh their pages when the code they are running is out of date.
It’s possible to ask the service worker to check if any updates have been deployed to the server. You might choose to do this if you have a site that changes frequently or want updates to happen on a schedule.
Do this with the checkForUpdate()
method:
check-for-update.service.ts
import { ApplicationRef, Injectable } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';
import { concat, interval } from 'rxjs';
import { first } from 'rxjs/operators';
@Injectable()
export class CheckForUpdateService {
constructor(appRef: ApplicationRef, updates: SwUpdate) {
// Allow the app to stabilize first, before starting polling for updates with `interval()`.
const appIsStable$ = appRef.isStable.pipe(first(isStable => isStable === true));
const everySixHours$ = interval(6 * 60 * 60 * 1000);
const everySixHoursOnceAppIsStable$ = concat(appIsStable$, everySixHours$);
everySixHoursOnceAppIsStable$.subscribe(() => updates.checkForUpdate());
}
}
This method returns a Promise
which indicates that the update check has completed successfully, though it does not indicate whether an update was discovered as a result of the check. Even if one is found, the service worker must still successfully download the changed files, which can fail. If successful, the available
event will indicate availability of a new version of the app.
In order to avoid negatively affecting the initial rendering, [ServiceWorkerModule](https://angular.io/api/service-worker/ServiceWorkerModule)
will by default wait for the app to stabilize, before registering the ServiceWorker script. Constantly polling for updates, e.g. with interval()
, will prevent the app from stabilizing and the ServiceWorker script will never be registered with the browser.
You can avoid that by waiting for the app to stabilize first, before starting to poll for updates (as shown in the example above).
Note that this is true for any kind of polling done by your application. Check the isStable documentation for more information.
If the current tab needs to be updated to the latest app version immediately, it can ask to do so with the activateUpdate()
method:
prompt-update.service.ts
@Injectable()
export class PromptUpdateService {
constructor(updates: SwUpdate) {
updates.available.subscribe(event => {
if (promptUser(event)) {
updates.activateUpdate().then(() => document.location.reload());
}
});
}
}
Doing this could break lazy-loading into currently running apps, especially if the lazy-loaded chunks use filenames with hashes, which change every version.
This page is a reference for deploying and supporting production apps that use the Angular service worker. It explains how the Angular service worker fits into the larger production environment, the service worker’s behavior under various conditions, and available resources and fail-safes.
Conceptually, you can imagine the Angular service worker as a forward cache or a CDN edge that is installed in the end user’s web browser. The service worker’s job is to satisfy requests made by the Angular app for resources or data from a local cache, without needing to wait for the network. Like any cache, it has rules for how content is expired and updated.
In the context of an Angular service worker, a “version” is a collection of resources that represent a specific build of the Angular app. Whenever a new build of the app is deployed, the service worker treats that build as a new version of the app. This is true even if only a single file is updated. At any given time, the service worker may have multiple versions of the app in its cache and it may be serving them simultaneously. For more information, see the App tabs section below.
To preserve app integrity, the Angular service worker groups all files into a version together. The files grouped into a version usually include HTML, JS, and CSS files. Grouping of these files is essential for integrity because HTML, JS, and CSS files frequently refer to each other and depend on specific content. For example, an index.html
file might have a <script>
tag that references bundle.js
and it might attempt to call a function startApp()
from within that script. Any time this version of index.html
is served, the corresponding bundle.js
must be served with it. For example, assume that the startApp()
function is renamed to runApp()
in both files. In this scenario, it is not valid to serve the old index.html
, which calls startApp()
, along with the new bundle, which defines runApp()
.
This file integrity is especially important when lazy loading modules. A JS bundle may reference many lazy chunks, and the filenames of the lazy chunks are unique to the particular build of the app. If a running app at version X
attempts to load a lazy chunk, but the server has updated to version X + 1
already, the lazy loading operation will fail.
The version identifier of the app is determined by the contents of all resources, and it changes if any of them change. In practice, the version is determined by the contents of the ngsw.json
file, which includes hashes for all known content. If any of the cached files change, the file’s hash will change in ngsw.json
, causing the Angular service worker to treat the active set of files as a new version.
With the versioning behavior of the Angular service worker, an application server can ensure that the Angular app always has a consistent set of files.
Every time the user opens or refreshes the application, the Angular service worker checks for updates to the app by looking for updates to the ngsw.json
manifest. If an update is found, it is downloaded and cached automatically, and will be served the next time the application is loaded.
One of the potential side effects of long caching is inadvertently caching an invalid resource. In a normal HTTP cache, a hard refresh or cache expiration limits the negative effects of caching an invalid file. A service worker ignores such constraints and effectively long caches the entire app. Consequently, it is essential that the service worker gets the correct content.
To ensure resource integrity, the Angular service worker validates the hashes of all resources for which it has a hash. Typically for an app created with the Angular CLI, this is everything in the dist
directory covered by the user’s src/ngsw-config.json
configuration.
If a particular file fails validation, the Angular service worker attempts to re-fetch the content using a “cache-busting” URL parameter to eliminate the effects of browser or intermediate caching. If that content also fails validation, the service worker considers the entire version of the app to be invalid and it stops serving the app. If necessary, the service worker enters a safe mode where requests fall back on the network, opting not to use its cache if the risk of serving invalid, broken, or outdated content is high.
Hash mismatches can occur for a variety of reasons:
ngsw.json
being updated. The reverse could also happen resulting in an updated ngsw.json
without updated resources.The only resources that have hashes in the ngsw.json
manifest are resources that were present in the dist
directory at the time the manifest was built. Other resources, especially those loaded from CDNs, have content that is unknown at build time or are updated more frequently than the app is deployed.
If the Angular service worker does not have a hash to validate a given resource, it still caches its contents but it honors the HTTP caching headers by using a policy of “stale while revalidate.” That is, when HTTP caching headers for a cached resource indicate that the resource has expired, the Angular service worker continues to serve the content and it attempts to refresh the resource in the background. This way, broken unhashed resources do not remain in the cache beyond their configured lifetimes.
It can be problematic for an app if the version of resources it’s receiving changes suddenly or without warning. See the Versions section above for a description of such issues.
The Angular service worker provides a guarantee: a running app will continue to run the same version of the app. If another instance of the app is opened in a new web browser tab, then the most current version of the app is served. As a result, that new tab can be running a different version of the app than the original tab.
It’s important to note that this guarantee is stronger than that provided by the normal web deployment model. Without a service worker, there is no guarantee that code lazily loaded later in a running app is from the same version as the initial code for the app.
There are a few limited reasons why the Angular service worker might change the version of a running app. Some of them are error conditions:
The Angular service worker is aware of which versions are in use at any given moment and it cleans up versions when no tab is using them.
Other reasons the Angular service worker might change the version of a running app are normal events:
[SwUpdate](https://angular.io/api/service-worker/SwUpdate)
service.The Angular service worker is a small script that runs in web browsers. From time to time, the service worker will be updated with bug fixes and feature improvements.
The Angular service worker is downloaded when the app is first opened and when the app is accessed after a period of inactivity. If the service worker has changed, the service worker will be updated in the background.
Most updates to the Angular service worker are transparent to the app—the old caches are still valid and content is still served normally. However, occasionally a bugfix or feature in the Angular service worker requires the invalidation of old caches. In this case, the app will be refreshed transparently from the network.
In some cases, you may want to bypass the service worker entirely and let the browser handle the request instead. An example is when you rely on a feature that is currently not supported in service workers (e.g. reporting progress on uploaded files).
To bypass the service worker you can set ngsw-bypass
as a request header, or as a query parameter. (The value of the header or query parameter is ignored and can be empty or omitted.)
Occasionally, it may be necessary to examine the Angular service worker in a running state to investigate issues or to ensure that it is operating as designed. Browsers provide built-in tools for debugging service workers and the Angular service worker itself includes useful debugging features.
The Angular service worker exposes debugging information under the ngsw/
virtual directory. Currently, the single exposed URL is ngsw/[state](https://angular.io/api/animations/state)
. Here is an example of this debug page’s contents:
NGSW Debug Info:
Driver state: NORMAL ((nominal))
Latest manifest hash: eea7f5f464f90789b621170af5a569d6be077e5c
Last update check: never
=== Version eea7f5f464f90789b621170af5a569d6be077e5c ===
Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65
=== Idle Task Queue ===
Last update tick: 1s496u
Last update run: never
Task queue:
* init post-load (update, cleanup)
Debug log:
The first line indicates the driver state:
Driver state: NORMAL ((nominal))
NORMAL
indicates that the service worker is operating normally and is not in a degraded state.
There are two possible degraded states:
EXISTING_CLIENTS_ONLY
: the service worker does not have a clean copy of the latest known version of the app. Older cached versions are safe to use, so existing tabs continue to run from cache, but new loads of the app will be served from the network. The service worker will try to recover from this state when a new version of the application is detected and installed (that is, when a new ngsw.json
is available).SAFE_MODE
: the service worker cannot guarantee the safety of using cached data. Either an unexpected error occurred or all cached versions are invalid. All traffic will be served from the network, running as little service worker code as possible.In both cases, the parenthetical annotation provides the error that caused the service worker to enter the degraded state.
Both states are temporary; they are saved only for the lifetime of the ServiceWorker instance. The browser sometimes terminates an idle service worker to conserve memory and processor power, and creates a new service worker instance in response to network events. The new instance starts in the NORMAL
mode, regardless of the state of the previous instance.
Latest manifest hash: eea7f5f464f90789b621170af5a569d6be077e5c
This is the SHA1 hash of the most up-to-date version of the app that the service worker knows about.
Last update check: never
This indicates the last time the service worker checked for a new version, or update, of the app. never
indicates that the service worker has never checked for an update.
In this example debug file, the update check is currently scheduled, as explained the next section.
=== Version eea7f5f464f90789b621170af5a569d6be077e5c ===
Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65
In this example, the service worker has one version of the app cached and being used to serve two different tabs. Note that this version hash is the “latest manifest hash” listed above. Both clients are on the latest version. Each client is listed by its ID from the Clients
API in the browser.
=== Idle Task Queue ===
Last update tick: 1s496u
Last update run: never
Task queue:
* init post-load (update, cleanup)
The Idle Task Queue is the queue of all pending tasks that happen in the background in the service worker. If there are any tasks in the queue, they are listed with a description. In this example, the service worker has one such task scheduled, a post-initialization operation involving an update check and cleanup of stale caches.
The last update tick/run counters give the time since specific events happened related to the idle queue. The “Last update run” counter shows the last time idle tasks were actually executed. “Last update tick” shows the time since the last event after which the queue might be processed.
Debug log:
Errors that occur within the service worker will be logged here.
Browsers such as Chrome provide developer tools for interacting with service workers. Such tools can be powerful when used properly, but there are a few things to keep in mind.
Stopping and starting the service worker in the Service Worker pane triggers a check for updates.
Like any complex system, bugs or broken configurations can cause the Angular service worker to act in unforeseen ways. While its design attempts to minimize the impact of such problems, the Angular service worker contains several failsafe mechanisms in case an administrator ever needs to deactivate the service worker quickly.
To deactivate the service worker, remove or rename the ngsw.json
file. When the service worker’s request for ngsw.json
returns a 404
, then the service worker removes all of its caches and de-registers itself, essentially self-destructing.
Also included in the @angular/service-worker
NPM package is a small script safety-worker.js
, which when loaded will unregister itself from the browser. This script can be used as a last resort to get rid of unwanted service workers already installed on client pages.
It’s important to note that you cannot register this worker directly, as old clients with cached state may not see a new index.html
which installs the different worker script. Instead, you must serve the contents of safety-worker.js
at the URL of the Service Worker script you are trying to unregister, and must continue to do so until you are certain all users have successfully unregistered the old worker. For most sites, this means that you should serve the safety worker at the old Service Worker URL forever.
This script can be used both to deactivate @angular/service-worker
as well as any other Service Workers which might have been served in the past on your site.
It is important to note that service workers don’t work behind redirect. You may have already encountered the error The script resource is behind a redirect, which is disallowed
.
This can be a problem if you have to change your app’s location. If you setup a redirect from the old location (for example example.com
) to the new location (for example www.example.com
) the worker will stop working. Also, the redirect won’t even trigger for users who are loading the site entirely from Service Worker. The old worker (registered at example.com
) tries to update and sends requests to the old location example.com
which get redirected to the new location www.example.com
and create the error The script resource is behind a redirect, which is disallowed
.
The ngsw-config.json
configuration file specifies which files and data URLs the Angular service worker should cache and how it should update the cached files and data. The Angular CLI processes the configuration file during ng build --prod
. Manually, you can process it with the ngsw-config
tool (where <project-name>
is the name of the project being built):
./node_modules/.bin/ngsw-config ./dist/<project-name> ./ngsw-config.json [/base/href]
The configuration file uses the JSON format. All file paths must begin with /
, which corresponds to the deployment directory—usually dist/<project-name>
in CLI projects.
Unless otherwise noted, patterns use a limited glob format:
**
matches 0 or more path segments.*
matches 0 or more characters excluding /
.?
matches exactly one character excluding /
.!
prefix marks the pattern as being negative, meaning that only files that don’t match the pattern will be included.Example patterns:
/**/*.html
specifies all HTML files./*.html
specifies only HTML files in the root.!/**/*.map
exclude all sourcemaps.Each section of the configuration file is described below.
appData
This section enables you to pass any data you want that describes this particular version of the app. The [SwUpdate](https://angular.io/api/service-worker/SwUpdate)
service includes that data in the update notifications. Many apps use this section to provide additional information for the display of UI popups, notifying users of the available update.
index
Specifies the file that serves as the index page to satisfy navigation requests. Usually this is /index.html
.
assetGroups
Assets are resources that are part of the app version that update along with the app. They can include resources loaded from the page’s origin as well as third-party resources loaded from CDNs and other external URLs. As not all such external URLs may be known at build time, URL patterns can be matched.
This field contains an array of asset groups, each of which defines a set of asset resources and the policy by which they are cached.
{
"assetGroups": [{
...
}, {
...
}]
}
Each asset group specifies both a group of resources and a policy that governs them. This policy determines when the resources are fetched and what happens when changes are detected.
Asset groups follow the Typescript interface shown here:
interface AssetGroup {
name: string;
installMode?: 'prefetch' | 'lazy';
updateMode?: 'prefetch' | 'lazy';
resources: {
files?: string[];
urls?: string[];
};
}
name
A name
is mandatory. It identifies this particular group of assets between versions of the configuration.
installMode
The installMode
determines how these resources are initially cached. The installMode
can be either of two values:
prefetch
tells the Angular service worker to fetch every single listed resource while it’s caching the current version of the app. This is bandwidth-intensive but ensures resources are available whenever they’re requested, even if the browser is currently offline.lazy
does not cache any of the resources up front. Instead, the Angular service worker only caches resources for which it receives requests. This is an on-demand caching mode. Resources that are never requested will not be cached. This is useful for things like images at different resolutions, so the service worker only caches the correct assets for the particular screen and orientation.Defaults to prefetch
.
updateMode
For resources already in the cache, the updateMode
determines the caching behavior when a new version of the app is discovered. Any resources in the group that have changed since the previous version are updated in accordance with updateMode
.
prefetch
tells the service worker to download and cache the changed resources immediately.lazy
tells the service worker to not cache those resources. Instead, it treats them as unrequested and waits until they’re requested again before updating them. An updateMode
of lazy
is only valid if the installMode
is also lazy
.Defaults to the value installMode
is set to.
resources
This section describes the resources to cache, broken up into the following groups:
files
lists patterns that match files in the distribution directory. These can be single files or glob-like patterns that match a number of files.urls
includes both URLs and URL patterns that will be matched at runtime. These resources are not fetched directly and do not have content hashes, but they will be cached according to their HTTP headers. This is most useful for CDNs such as the Google Fonts service._?_
will be matched literally; i.e. it will not match any character other than _?_
.)dataGroups
Unlike asset resources, data requests are not versioned along with the app. They’re cached according to manually-configured policies that are more useful for situations such as API requests and other data dependencies.
Data groups follow this Typescript interface:
export interface DataGroup {
name: string;
urls: string[];
version?: number;
cacheConfig: {
maxSize: number;
maxAge: string;
timeout?: string;
strategy?: 'freshness' | 'performance';
};
}
name
Similar to assetGroups
, every data group has a name
which uniquely identifies it.
urls
A list of URL patterns. URLs that match these patterns are cached according to this data group’s policy. Only non-mutating requests (GET and HEAD) are cached.
?
is matched literally; that is, it matches only the character ?
.version
Occasionally APIs change formats in a way that is not backward-compatible. A new version of the app may not be compatible with the old API format and thus may not be compatible with existing cached resources from that API.
version
provides a mechanism to indicate that the resources being cached have been updated in a backwards-incompatible way, and that the old cache entries—those from previous versions—should be discarded.
version
is an integer field and defaults to 1
.
cacheConfig
This section defines the policy by which matching requests will be cached.
maxSize
(required) The maximum number of entries, or responses, in the cache. Open-ended caches can grow in unbounded ways and eventually exceed storage quotas, calling for eviction.
maxAge
(required) The maxAge
parameter indicates how long responses are allowed to remain in the cache before being considered invalid and evicted. maxAge
is a duration string, using the following unit suffixes:
d
: daysh
: hoursm
: minutess
: secondsu
: millisecondsFor example, the string 3d12h
will cache content for up to three and a half days.
timeout
This duration string specifies the network timeout. The network timeout is how long the Angular service worker will wait for the network to respond before using a cached response, if configured to do so. timeout
is a duration string, using the following unit suffixes:
d
: daysh
: hoursm
: minutess
: secondsu
: millisecondsFor example, the string 5s30u
will translate to five seconds and 30 milliseconds of network timeout.
strategy
The Angular service worker can use either of two caching strategies for data resources.
performance
, the default, optimizes for responses that are as fast as possible. If a resource exists in the cache, the cached version is used, and no network request is made. This allows for some staleness, depending on the maxAge
, in exchange for better performance. This is suitable for resources that don’t change often; for example, user avatar images.freshness
optimizes for currency of data, preferentially fetching requested data from the network. Only if the network times out, according to timeout
, does the request fall back to the cache. This is useful for resources that change frequently; for example, account balances.navigationUrls
This optional section enables you to specify a custom list of URLs that will be redirected to the index file.
The ServiceWorker will redirect navigation requests that don’t match any asset
or data
group to the specified index file. A request is considered to be a navigation request if:
navigation
.text/html
response (as determined by the value of the Accept
header).By default, these criteria are:
.
) in the last path segment.__
.While these default criteria are fine in most cases, it is sometimes desirable to configure different rules. For example, you may want to ignore specific routes (that are not part of the Angular app) and pass them through to the server.
This field contains an array of URLs and glob-like URL patterns that will be matched at runtime. It can contain both negative patterns (i.e. patterns starting with !
) and non-negative patterns and URLs.
Only requests whose URLs match any of the non-negative URLs/patterns and none of the negative ones will be considered navigation requests. The URL query will be ignored when matching.
If the field is omitted, it defaults to:
[
'/**', // Include all URLs.
'!/**/*.*', // Exclude URLs to files.
'!/**/*__*', // Exclude URLs containing `__` in the last segment.
'!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
]
Build your First Angular PWA from Scratch (Angular 6 PWA Tutorial)
Today’s Question: Have you or are you planning on building a PWA?
– In this Angular 6 PWA tutorial, I’m going to show you how to create a PWA (Progressive Web App) based on Angular 6. PWA’s are awesome, in that they allow your apps to work offline, and they bypass the app stores; users can install them on their home screens! Hang tight, as I will be covering more PWA related content soon.
Github project for this lesson: https://github.com/designcourse/angular-6-pwa
Angular Service Worker | Progressive Web Apps Development
A service worker is a script that browser runs in the background, separate from a web page. With the help of the service worker, we can also implement push notification and background sync. Service workers can store files or responses in cache storage so it allows developers to create an offline experience for the user.
Service Worker in angular can be achieved by adding @angular/pwa package, this will going to handle lots of boilerplate code for us like registering a service worker, installing a service worker, and activating the service worker and lots more.
GitHub: https://github.com/funOfheuristic/angular-pwa
#angular #web-development #pwa #javascript