docs(service-worker): minor fixes/improvements (#23339)

PR Close #23339
This commit is contained in:
George Kalpakas 2018-04-12 18:34:57 +03:00 committed by Igor Minar
parent 639d52fe71
commit d1e716b2cb
3 changed files with 136 additions and 141 deletions

View File

@ -1,5 +1,3 @@
{@a glob}
# Service worker configuration # Service worker configuration
#### Prerequisites #### Prerequisites
@ -9,9 +7,9 @@ A basic understanding of the following:
<hr /> <hr />
The `src/ngsw-config.json` configuration file specifies which files and data URLs the Angular The `src/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 service worker should cache and how it should update the cached files and data. The
CLI processes the configuration file during `ng build --prod`. Manually, you can process CLI processes the configuration file during `ng build --prod`. Manually, you can process
it with the `ngsw-config` tool: it with the `ngsw-config` tool:
```sh ```sh
@ -32,7 +30,7 @@ Example patterns:
* `/*.html` specifies only HTML files in the root. * `/*.html` specifies only HTML files in the root.
* `!/**/*.map` exclude all sourcemaps. * `!/**/*.map` exclude all sourcemaps.
Each section of the configuration file is described below. Each section of the configuration file is described below.
## `appData` ## `appData`
@ -92,7 +90,7 @@ The `installMode` determines how these resources are initially cached. The `inst
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`. 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. * `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`. * `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`.
@ -135,7 +133,7 @@ A list of URL patterns. URLs that match these patterns will be cached according
### `version` ### `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. 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&mdash;those from previous versions&mdash;should be discarded. `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&mdash;those from previous versions&mdash;should be discarded.
`version` is an integer field and defaults to `0`. `version` is an integer field and defaults to `0`.
@ -166,4 +164,3 @@ The Angular service worker can use either of two caching strategies for data res
* `performance`, the default, optimizes for responses that are as fast as possible. If a resource exists in the cache, the cached version is used. 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. * `performance`, the default, optimizes for responses that are as fast as possible. If a resource exists in the cache, the cached version is used. 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. * `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.

View File

@ -21,20 +21,20 @@ In the context of an Angular service worker, a "version" is a collection of reso
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()`. 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. This file integrity is especially important when lazy loading modules.
A JS bundle may reference many lazy chunks, and the filenames of the 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 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 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. 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 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 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 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 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 hash will change in `ngsw.json`, causing the Angular service worker to
treat the active set of files as a new version. treat the active set of files as a new version.
With the versioning behavior of the Angular service worker, an application 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. server can ensure that the Angular app always has a consistent set of files.
#### Update checks #### Update checks
@ -46,25 +46,25 @@ the next time the application is loaded.
### Resource integrity ### Resource integrity
One of the potential side effects of long caching is inadvertently One of the potential side effects of long caching is inadvertently
caching an invalid resource. In a normal HTTP cache, a hard refresh caching an invalid resource. In a normal HTTP cache, a hard refresh
or cache expiration limits the negative effects of caching an invalid or cache expiration limits the negative effects of caching an invalid
file. A service worker ignores such constraints and effectively long file. A service worker ignores such constraints and effectively long
caches the entire app. Consequently, it is essential that the service worker caches the entire app. Consequently, it is essential that the service worker
get the correct content. gets the correct content.
To ensure resource integrity, the Angular service worker validates To ensure resource integrity, the Angular service worker validates
the hashes of all resources for which it has a hash. Typically for the hashes of all resources for which it has a hash. Typically for
a CLI app, this is everything in the `dist` directory covered by a CLI app, this is everything in the `dist` directory covered by
the user's `src/ngsw-config.json` configuration. the user's `src/ngsw-config.json` configuration.
If a particular file fails validation, the Angular service worker If a particular file fails validation, the Angular service worker
attempts to re-fetch the content using a "cache-busting" URL attempts to re-fetch the content using a "cache-busting" URL
parameter to eliminate the effects of browser or intermediate parameter to eliminate the effects of browser or intermediate
caching. If that content also fails validation, the service worker caching. If that content also fails validation, the service worker
considers the entire version of the app to be invalid and it stops 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 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 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. if the risk of serving invalid, broken, or outdated content is high.
Hash mismatches can occur for a variety of reasons: Hash mismatches can occur for a variety of reasons:
@ -75,57 +75,57 @@ Hash mismatches can occur for a variety of reasons:
#### Unhashed content #### Unhashed content
The only resources that have hashes in the `ngsw.json` The only resources that have hashes in the `ngsw.json`
manifest are resources that were present in the `dist` manifest are resources that were present in the `dist`
directory at the time the manifest was built. Other directory at the time the manifest was built. Other
resources, especially those loaded from CDNs, have resources, especially those loaded from CDNs, have
content that is unknown at build time or are updated content that is unknown at build time or are updated
more frequently than the app is deployed. more frequently than the app is deployed.
If the Angular service worker does not have a hash to validate If the Angular service worker does not have a hash to validate
a given resource, it still caches its contents but it honors a given resource, it still caches its contents but it honors
the HTTP caching headers by using a policy of "stale while the HTTP caching headers by using a policy of "stale while
revalidate." That is, when HTTP caching headers for a cached revalidate." That is, when HTTP caching headers for a cached
resource indicate that the resource has expired, the Angular resource indicate that the resource has expired, the Angular
service worker continues to serve the content and it attempts service worker continues to serve the content and it attempts
to refresh the resource in the background. This way, broken to refresh the resource in the background. This way, broken
unhashed resources do not remain in the cache beyond their unhashed resources do not remain in the cache beyond their
configured lifetimes. configured lifetimes.
{@a tabs} {@a tabs}
### App tabs ### App tabs
It can be problematic for an app if the version of resources It can be problematic for an app if the version of resources
it's receiving changes suddenly or without warning. See the it's receiving changes suddenly or without warning. See the
[Versions](guide/service-worker-devops#versions) section above [Versions](guide/service-worker-devops#versions) section above
for a description of such issues. for a description of such issues.
The Angular service worker provides a guarantee: a running app The Angular service worker provides a guarantee: a running app
will continue to run the same version of the app. If another 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 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, the most current version of the app is served. As a result,
that new tab can be running a different version of the app that new tab can be running a different version of the app
than the original tab. than the original tab.
It's important to note that this guarantee is **stronger** It's important to note that this guarantee is **stronger**
than that provided by the normal web deployment model. Without than that provided by the normal web deployment model. Without
a service worker, there is no guarantee that code lazily loaded a service worker, there is no guarantee that code lazily loaded
later in a running app is from the same version as the initial later in a running app is from the same version as the initial
code for the app. code for the app.
There are a few limited reasons why the Angular service worker There are a few limited reasons why the Angular service worker
might change the version of a running app. Some of them are might change the version of a running app. Some of them are
error conditions: error conditions:
* The current version becomes invalid due to a failed hash. * The current version becomes invalid due to a failed hash.
* An unrelated error causes the service worker to enter safe mode; that is, temporary deactivation. * An unrelated error causes the service worker to enter safe mode; that is, temporary deactivation.
The Angular service worker is aware of which versions are in The Angular service worker is aware of which versions are in
use at any given moment and it cleans up versions when use at any given moment and it cleans up versions when
no tab is using them. no tab is using them.
Other reasons the Angular service worker might change the version Other reasons the Angular service worker might change the version
of a running app are normal events: of a running app are normal events:
* The page is reloaded/refreshed. * The page is reloaded/refreshed.
@ -133,33 +133,33 @@ of a running app are normal events:
### Service worker updates ### Service worker updates
The Angular service worker is a small script that runs in web browsers. 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 From time to time, the service worker will be updated with bug
fixes and feature improvements. fixes and feature improvements.
The Angular service worker is downloaded when the app is first opened 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 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. service worker has changed, the service worker will be updated in the background.
Most updates to the Angular service worker are transparent to the Most updates to the Angular service worker are transparent to the
app&mdash;the old caches are still valid and content is still served app&mdash;the old caches are still valid and content is still served
normally. However, occasionally a bugfix or feature in the Angular normally. However, occasionally a bugfix or feature in the Angular
service worker requires the invalidation of old caches. In this case, service worker requires the invalidation of old caches. In this case,
the app will be refreshed transparently from the network. the app will be refreshed transparently from the network.
## Debugging the Angular service worker ## Debugging the Angular service worker
Occasionally, it may be necessary to examine the Angular service Occasionally, it may be necessary to examine the Angular service
worker in a running state to investigate issues or to ensure that worker in a running state to investigate issues or to ensure that
it is operating as designed. Browsers provide built-in tools for it is operating as designed. Browsers provide built-in tools for
debugging service workers and the Angular service worker itself debugging service workers and the Angular service worker itself
includes useful debugging features. includes useful debugging features.
### Locating and analyzing debugging information ### Locating and analyzing debugging information
The Angular service worker exposes debugging information under The Angular service worker exposes debugging information under
the `ngsw/` virtual directory. Currently, the single exposed URL the `ngsw/` virtual directory. Currently, the single exposed URL
is `ngsw/state`. Here is an example of this debug page's contents: is `ngsw/state`. Here is an example of this debug page's contents:
``` ```
@ -184,27 +184,27 @@ Debug log:
#### Driver state #### Driver state
The first line indicates the driver state: The first line indicates the driver state:
``` ```
Driver state: NORMAL ((nominal)) Driver state: NORMAL ((nominal))
``` ```
`NORMAL` indicates that the service worker is operating normally and is not in a degraded state. `NORMAL` indicates that the service worker is operating normally and is not in a degraded state.
There are two possible degraded states: There are two possible degraded states:
* `EXISTING_CLIENTS_ONLY`: the service worker does not have a * `EXISTING_CLIENTS_ONLY`: the service worker does not have a
clean copy of the latest known version of the app. Older cached clean copy of the latest known version of the app. Older cached
versions are safe to use, so existing tabs continue to run from 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. cache, but new loads of the app will be served from the network.
* `SAFE_MODE`: the service worker cannot guarantee the safety of * `SAFE_MODE`: the service worker cannot guarantee the safety of
using cached data. Either an unexpected error occurred or all using cached data. Either an unexpected error occurred or all
cached versions are invalid. All traffic will be served from the cached versions are invalid. All traffic will be served from the
network, running as little service worker code as possible. network, running as little service worker code as possible.
In both cases, the parenthetical annotation provides the In both cases, the parenthetical annotation provides the
error that caused the service worker to enter the degraded state. error that caused the service worker to enter the degraded state.
@ -223,7 +223,7 @@ This is the SHA1 hash of the most up-to-date version of the app that the service
Last update check: never 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. 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. In this example debug file, the update check is currently scheduled, as explained the next section.
@ -235,10 +235,10 @@ In this example debug file, the update check is currently scheduled, as explaine
Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65 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 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 being used to serve two different tabs. Note that this version hash
is the "latest manifest hash" listed above. Both clients are on the is the "latest manifest hash" listed above. Both clients are on the
latest version. Each client is listed by its ID from the `Clients` latest version. Each client is listed by its ID from the `Clients`
API in the browser. API in the browser.
@ -252,16 +252,16 @@ Task queue:
* init post-load (update, cleanup) * init post-load (update, cleanup)
``` ```
The Idle Task Queue is the queue of all pending tasks that happen 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 background in the service worker. If there are any tasks
in the queue, they are listed with a description. In this example, in the queue, they are listed with a description. In this example,
the service worker has one such task scheduled, a post-initialization the service worker has one such task scheduled, a post-initialization
operation involving an update check and cleanup of stale caches. operation involving an update check and cleanup of stale caches.
The last update tick/run counters give the time since specific The last update tick/run counters give the time since specific
events happened related to the idle queue. The "Last update run" events happened related to the idle queue. The "Last update run"
counter shows the last time idle tasks were actually executed. counter shows the last time idle tasks were actually executed.
"Last update tick" shows the time since the last event after "Last update tick" shows the time since the last event after
which the queue might be processed. which the queue might be processed.
@ -276,34 +276,34 @@ Errors that occur within the service worker will be logged here.
### Developer Tools ### Developer Tools
Browsers such as Chrome provide developer tools for interacting Browsers such as Chrome provide developer tools for interacting
with service workers. Such tools can be powerful when used properly, with service workers. Such tools can be powerful when used properly,
but there are a few things to keep in mind. but there are a few things to keep in mind.
* When using developer tools, the service worker is kept running * When using developer tools, the service worker is kept running
in the background and never restarts. This can cause behavior with Dev in the background and never restarts. This can cause behavior with Dev
Tools open to differ from behavior a user might experience. Tools open to differ from behavior a user might experience.
* If you look in the Cache Storage viewer, the cache is frequently * If you look in the Cache Storage viewer, the cache is frequently
out of date. Right click the Cache Storage title and refresh the caches. out of date. Right click the Cache Storage title and refresh the caches.
Stopping and starting the service worker in the Service Worker Stopping and starting the service worker in the Service Worker
pane triggers a check for updates. pane triggers a check for updates.
## Service Worker Safety ## Service Worker Safety
Like any complex system, bugs or broken configurations can cause Like any complex system, bugs or broken configurations can cause
the Angular service worker to act in unforeseen ways. While its the Angular service worker to act in unforeseen ways. While its
design attempts to minimize the impact of such problems, the design attempts to minimize the impact of such problems, the
Angular service worker contains several failsafe mechanisms in case Angular service worker contains several failsafe mechanisms in case
an administrator ever needs to deactivate the service worker quickly. an administrator ever needs to deactivate the service worker quickly.
## Fail-safe ### Fail-safe
To deactivate the service worker, remove or rename the To deactivate the service worker, remove or rename the
`ngsw-config.json` file. When the service worker's request `ngsw-config.json` file. When the service worker's request
for `ngsw.json` returns a `404`, then the service worker for `ngsw.json` returns a `404`, then the service worker
removes all of its caches and de-registers itself, removes all of its caches and de-registers itself,
essentially self-destructing. essentially self-destructing.
### Safety Worker ### Safety Worker

View File

@ -8,21 +8,21 @@ A basic understanding of the following:
<hr /> <hr />
Beginning in Angular 5.0.0, you can easily enable Angular service worker support in any CLI project. This document explains how to enable Angular service worker support in new and existing projects. It then uses a simple example to show you a service worker in action, demonstrating loading and basic caching. Beginning in Angular 5.0.0, you can easily enable Angular service worker support in any CLI project. This document explains how to enable Angular service worker support in new and existing projects. It then uses a simple example to show you a service worker in action, demonstrating loading and basic caching.
## Adding a service worker to a new application ## Adding a service worker to a new application
If you're generating a new CLI project, you can use the CLI to set up the Angular service worker as part of creating the project. To do so, add the `--service-worker` flag to the `ng new` command: If you're generating a new CLI project, you can use the CLI to set up the Angular service worker as part of creating the project. To do so, add the `--service-worker` flag to the `ng new` command:
```sh ```sh
ng new my-project --service-worker ng new my-project --service-worker
``` ```
The `--service-worker` flag takes care of configuring your app to The `--service-worker` flag takes care of configuring your app to
use service workers by adding the `service-worker` package along use service workers by adding the `service-worker` package along
with setting up the necessary files to support service workers. with setting up the necessary files to support service workers.
For information on the details, see the following section For information on the details, see the following section
which covers the process in detail as it shows you how to add a which covers the process in detail as it shows you how to add a
service worker manually to an existing app. service worker manually to an existing app.
@ -34,7 +34,7 @@ To add a service worker to an existing app:
1. Add the service worker package. 1. Add the service worker package.
2. Enable service worker build support in the CLI. 2. Enable service worker build support in the CLI.
3. Import and register the service worker. 3. Import and register the service worker.
4. Create the service worker configuration file, which specifies the caching behaviors and other settings. 4. Create the service worker configuration file, which specifies the caching behaviors and other settings.
5. Build the project. 5. Build the project.
### Step 1: Add the service worker package ### Step 1: Add the service worker package
@ -70,7 +70,7 @@ The file `ngsw-worker.js` is the name of the prebuilt service worker script, whi
### Step 4: Create the configuration file, `ngsw-config.json` ### Step 4: Create the configuration file, `ngsw-config.json`
The Angular CLI needs a service worker configuration file, called `ngsw-config.json`. The configuration file controls how the service worker caches files and data The Angular CLI needs a service worker configuration file, called `ngsw-config.json`. The configuration file controls how the service worker caches files and data
resources. resources.
You can begin with the boilerplate version from the CLI, which configures sensible defaults for most applications. You can begin with the boilerplate version from the CLI, which configures sensible defaults for most applications.
@ -81,7 +81,7 @@ Alternately, save the following as `src/ngsw-config.json`:
### Step 5: Build the project ### Step 5: Build the project
Finally, build the project: Finally, build the project:
```sh ```sh
ng build --prod ng build --prod
@ -92,18 +92,17 @@ The CLI project is now set up to use the Angular service worker.
## Service worker in action: a tour ## Service worker in action: a tour
This section demonstrates a service worker in action, This section demonstrates a service worker in action,
using an example application. using an example application.
### Serving with `http-server` ### Serving with `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](https://www.npmjs.com/package/http-server) package from npm. To reduce the possibility of conflicts, test on a dedicated port. 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](https://www.npmjs.com/package/http-server) package from npm. To reduce the possibility of conflicts, test on a dedicated port.
To serve with `http-server`, change to the directory containing your web files and start the web server: To serve the app, start `http-server` and specify the directory containing your web files and the port:
```sh ```sh
cd dist http-server dist -p 8080
http-server -p 8080
``` ```
### Initial load ### Initial load
@ -114,7 +113,7 @@ With the server running, you can point your browser at http://localhost:8080/. Y
### Simulating a network issue ### Simulating a network issue
To simulate a network issue, disable network interaction for your application. In Chrome: To simulate a network issue, disable network interaction for your application. In Chrome:
1. Select **Tools** > **Developer Tools** (from the Chrome menu located at the top right corner). 1. Select **Tools** > **Developer Tools** (from the Chrome menu located at the top right corner).
2. Go to the **Network tab**. 2. Go to the **Network tab**.
@ -126,9 +125,9 @@ To simulate a network issue, disable network interaction for your application. I
Now the app has no access to network interaction. 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". 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. 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. If you look at the Network tab, you can verify that the service worker is active.
@ -150,12 +149,12 @@ Notice that all of the files the browser needs to render this application are ca
### Making changes to your application ### Making changes to your application
Now that you've seen how service workers cache your application, the Now that you've seen how service workers cache your application, the
next step is understanding how updates work. next step is understanding how updates work.
1. If you're testing in an incognito window, open a second blank tab. This will keep the incognito and the cache state alive during your test. 1. If you're testing in an incognito window, open a second blank tab. This will keep the incognito and the cache state alive during your test.
2. Close the application tab, but not the window. This should also close the Developer Tools. 2. Close the application tab, but not the window. This should also close the Developer Tools.
3. Shut down `http-server`. 3. Shut down `http-server`.
@ -169,8 +168,7 @@ next step is understanding how updates work.
```sh ```sh
ng build --prod ng build --prod
cd dist http-server dist -p 8080
http-server -p 8080
``` ```
### Updating your application in the browser ### Updating your application in the browser