Angular 的 Service Worker 簡介

Angular service worker introduction

Service Worker 可以增強傳統的 Web 發佈模式,並使應用程式能夠提供可與原生程式碼媲美的高可靠、高效能的使用者體驗。為 Angular 應用新增 Service Worker 是把應用轉換成漸進式應用(PWA)的步驟之一。

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).

簡單來說,Service Worker 就是一段執行在 Web 瀏覽器中,並為應用管理快取的指令碼。

At its simplest, a service worker is a script that runs in the web browser and manages caching for an application.

Service Worker 的功能就像一個網路代理。它們會攔截所有由應用發出的 HTTP 請求,並選擇如何給出響應。 比如,它們可以查詢區域性快取,如果有快取的響應資料,就用它做出響應。 這種代理行為不會侷限於透過程式呼叫 API(比如 fetch)發起的請求,還包括 HTML 中對資源的參考,甚至對 index.html 的首次請求。 基於 Service Worker 的快取是完全可程式設計的,並且不依賴於伺服器端指定的那些控制快取策略的頭。

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.

不像應用中的其它指令碼(如 Angular 的應用包),Service Worker 在使用者關閉瀏覽器頁標籤時仍然會被保留。 下次瀏覽器載入本應用時,Service Worker 會首先載入,然後攔截載入本應用時的對每一項資源的請求。 如果這個 Service Worker 就是為此而設計的,它就能完全滿足應用載入時的需求,而不需要依賴網路

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.

即使在快速可靠的網路中,往返延遲也可能在載入應用程式時產生顯著的延遲。使用 Service Worker 來減少對網路的依賴可以顯著改善使用者體驗。

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 中的 Service Worker

Service workers in Angular

作為單頁面應用,Angular 應用可以受益於 Service Worker 的優勢。 從 Angular v5.0.0 開始,Angular 提供了一份 Service Worker 的實現。 Angular 開發人員可以利用 Service Worker,並受益於其增強的可靠性和效能,而無需再針對底層 API 寫程式碼。

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 的 Service Worker 的設計目標是優化那些使用慢速、不可靠網路的終端使用者的體驗,同時還要儘可能減小提供過期內容的風險。

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.

Angular 的 Service Worker 的行為遵循下列設計目標:

The Angular service worker's behavior follows that design goal:

  • 像安裝原生應用一樣快取應用。該應用作為整體被快取,它的所有檔案作為整體進行更新。

    Caching an application is like installing a native application. The application is cached as one unit, and all files update together.

  • 正在執行的應用使用所有檔案的同一版本繼續執行。不要突然開始接收來自新版本的、可能不相容的快取檔案。

    A running application continues to run with the same version of all files. It does not suddenly start receiving cached files from a newer version, which are likely incompatible.

  • 當用戶重新整理本應用時,他們會看到最新的被完全快取的版本。新的頁標籤中會載入最新的快取程式碼。

    When users refresh the application, they see the latest fully cached version. New tabs load the latest cached code.

  • 在更改發佈之後,相對較快的在後臺進行更新。在一次完整的更新完成之前,仍然使用應用的上一個版本。

    Updates happen in the background, relatively quickly after changes are published. The previous version of the application is served until an update is installed and ready.

  • 只要有可能,Service Worker 就會盡量節省頻寬。它只會下載那些發生了變化的資源。

    The service worker conserves bandwidth when possible. Resources are only downloaded if they've changed.

要支援這些行為,Angular 的 Service Worker 會從伺服器上下載一個 manifest 檔案。 這個 manifest 檔案描述要快取的資源,幷包含每個檔案內容的雜湊值。 當發佈了應用的一個新版本時,manifest 的內容就會改變,通知 Service Worker 應該下載並快取應用的一個新版本了。 這個 manifest 是從 CLI 產生的一個名叫 ngsw-config.json 的檔案中產生的。

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.

安裝 Angular 的 Service Worker 就像引入一個 NgModule 一樣簡單。 除了使用瀏覽器註冊 Angular 的 Service Worker 之外,還要製作一些可供注入的服務,它們可以與 Service Worker 互動,並控制它。 比如,應用可以要求當新的更新已經就緒時通知自己,或要求 Service Worker 檢查伺服器,看是否有可用的更新。

Installing the Angular service worker is as simple as including an 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.



要使用 Angular Service Worker 的所有功能,請使用最新版本的 Angular 和 Angular CLI。

To make use of all the features of Angular service worker, use the latest versions of Angular and the Angular CLI.

為了註冊 Service Worker,必須透過 HTTPS 而非 HTTP 訪問該應用程式。瀏覽器會忽略透過不安全連線訪問的頁面上的 Service Worker。原因是 Service Worker 非常強大,因此需要格外小心,以確保 Service Worker 的指令碼未被篡改。

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.

這條規則有一個例外:為了方便本地開發,當訪問 localhost 上的應用時,瀏覽器要求安全連線。

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.


Browser support

要從 Angular Service Worker 中受益,你的應用必須在支援 Service Worker 的 Web 瀏覽器中執行。 當前,最新版本的 Chrome,Firefox,Edge,Safari,Opera,UC 瀏覽器(Android 版)和 Samsung Internet 支援 Service Worker。而 IE 和 Opera Mini 等瀏覽器不支援 Service Worker。

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.

如果使用者透過不支援 Service Worker 的瀏覽器訪問你的應用程式,則該 Service Worker 不會註冊,並且不會發生相關行為,例如離線快取管理和推送通知。進一步來說:

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:

  • 瀏覽器不會下載 Service Worker 指令碼和 ngsw.json 清單檔案。

    The browser does not download the service worker script and ngsw.json manifest file.

  • 主動嘗試與 Service Worker 進行互動,例如呼叫 SwUpdate.checkForUpdate(),會返回被拒絕的承諾(Promise)。

    Active attempts to interact with the service worker, such as calling SwUpdate.checkForUpdate(), return rejected promises.

  • 相關服務(例如 SwUpdate.available)的可觀察事件不會觸發。

    The observable events of related services, such as SwUpdate.available, are not triggered.

強烈建議你確保即使在瀏覽器中沒有 Service Worker 支援的情況下,你的應用也可以正常執行。儘管不受支援的瀏覽器會忽略 Service Worker 快取,但如果應用程式嘗試與 Service Worker 進行互動,它將仍然會報告錯誤。例如,呼叫 SwUpdate.checkForUpdate() 將返回被拒絕的承諾。為避免此類別錯誤,你可以使用 SwUpdate.isEnabled() 檢查是否啟用了 Angular Service Worker。

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() will return rejected promises. To avoid such an error, you can check whether the Angular service worker is enabled using SwUpdate.isEnabled().

要了解關於其它支援 Service Worker 的瀏覽器的更多資訊,請參閱 Can I Use 頁面和 MDN 文件

To learn more about other browsers that are service worker ready, see the Can I Use page and MDN docs.

本節中的其餘文章專門針對 Service Worker 的 Angular 實現。

The rest of the articles in this section specifically address the Angular implementation of service workers.

要了解更多關於 Service Worker 的普遍性資訊,參閱 Service Worker 簡介

For more information about service workers in general, see Service Workers: an Introduction.

要了解關於瀏覽器支援度的更多資訊,參閱 Service Worker 簡介 中的瀏覽器支援部分、Jake Archibald 寫的Serviceworker 好了嗎?Can I Use

For more information about browser support, see the browser support section of Service Workers: an Introduction, Jake Archibald's Is Serviceworker ready?, and Can I Use.


For additional recommendations and examples, see:


Next steps

要開始使用 Angular Serivce Worker,參閱 Service Worker 快速上手

To begin using Angular service workers, see Getting Started with service workers.