Angular Service Worker配置

2022-07-12 11:15 更新

前提條件

對下列知識有基本的了解:

配置文件 ?ngsw-config.json? 指定了 Angular Service Worker 應(yīng)該緩存哪些文件和數(shù)據(jù)的 URL,以及如何更新緩存的文件和數(shù)據(jù)。?Angular CLI? 會在 ?ng build? 期間處理配置文件。如果想手動處理,可以用 ?ngsw-config? 工具(這里的 ?<project-name>? 就是要構(gòu)建的項目名):

./node_modules/.bin/ngsw-config ./dist/<project-name> ./ngsw-config.json [/base/href]

該配置文件使用 JSON 格式。所有文件路徑都必須以 ?/? 開頭,也就是相應(yīng)的部署目錄 —— 在 CLI 項目中的它通常是 ?dist/<project-name>?。

除非另有注釋,否則模式使用limited* glob 格式,該格式將在內(nèi)部轉(zhuǎn)換為正則表達式:

GLOB 格式

詳情

**

匹配 0 個或多個路徑段

*

匹配不包括 / 的 0 個或多個字符

?

正好匹配不包括 / 的一個字符

! 前綴

將模式標(biāo)記為負數(shù),這意味著僅包含與模式不匹配的文件

請注意,在內(nèi)部 glob 到正則表達式的轉(zhuǎn)換中,正則表達式中某些具有特殊含義的字符不會被轉(zhuǎn)義,并且模式不會用 ?^? / ?$? 包裝。
  • ?$? 是正則表達式中的一個特殊字符,它與字符串的結(jié)尾匹配,在將 glob 模式轉(zhuǎn)換為正則表達式時不會自動轉(zhuǎn)義。如果你想從字面上匹配 ?$? 字符,則必須自己對它進行轉(zhuǎn)譯(使用 ?\\$?)。
  • 例如,glob 模式 ?/foo/bar/$value? 會導(dǎo)致出現(xiàn)無法匹配的表達式,因為字符串不可能在結(jié)尾后有任何字符。

  • 將模式轉(zhuǎn)換為正則表達式時,不會自動用 ?^? 和 ?$? 包裝。因此,這些模式將部分匹配請求 URL。如果你希望你的模式匹配 URL 的開頭和/或結(jié)尾,可以自己添加 ?^? / ?$?。
  • 例如,glob 模式 ?/foo/bar/*.js? 將匹配 ?.js? 和 ?.json? 文件。如果你想僅匹配 ?.js? 文件,請使用 ?/foo/bar/*.js$?。

范例模式:

模式

詳情

/**/*.html

指定所有 HTML 文件

/*.html

僅指定根中的 HTML 文件

!/**/*.map

排除所有源映射

下面講講配置文件中的每個屬性。

appData

本節(jié)允許你傳遞用來描述這個特定應(yīng)用版本的任何數(shù)據(jù)。?SwUpdate ?服務(wù)會在更新通知中包含這些數(shù)據(jù)。許多應(yīng)用會使用本節(jié)來提供 UI 彈窗時要顯示的附加信息,以通知用戶有可用的更新。

index

指定用來充當(dāng)索引頁的文件以滿足導(dǎo)航請求。通常是 ?/index.html?。

assetGroups

資產(chǎn)(Assets)是與應(yīng)用一起更新的應(yīng)用版本的一部分。它們可以包含從頁面的同源地址加載的資源以及從 CDN 和其它外部 URL 加載的第三方資源。由于在構(gòu)建時可能沒法提前知道所有這些外部 URL,因此也可以指定 URL 的模式。

該字段包含一個資產(chǎn)組的數(shù)組,每個資產(chǎn)組中會定義一組資產(chǎn)資源和它們的緩存策略。

{
  "assetGroups": [
    {
      …
    },
    {
      …
    }
  ]
}
當(dāng) ServiceWorker 處理請求時,它將按照資源組在 ?ngsw-config.json? 中出現(xiàn)的順序?qū)ζ溥M行檢查。與所請求的資源匹配的第一個資源組將處理該請求。
建議將更具體的資源組放在列表中較高的位置。比如,與 ?/foo.js? 匹配的資源組應(yīng)出現(xiàn)在與 ?*.js? 匹配的資源組之前。

每個資產(chǎn)組都會指定一組資源和一個管理它們的策略。此策略用來決定何時獲取資源以及當(dāng)檢測到更改時該怎么做。

這些資產(chǎn)組會遵循下面的 Typescript 接口:

interface AssetGroup {
  name: string;
  installMode?: 'prefetch' | 'lazy';
  updateMode?: 'prefetch' | 'lazy';
  resources: {
    files?: string[];
    urls?: string[];
  };
  cacheQueryOptions?: {
    ignoreSearch?: boolean;
  };
}

name

?name ?是強制性的。它用來標(biāo)識該配置文件版本中這個特定的資產(chǎn)組。

installMode

?installMode ?決定了這些資源最初的緩存方式。?installMode ?可以取如下兩個值之一:

詳情

prefetch

要求 Angular Service Worker 在緩存當(dāng)前版本的應(yīng)用時要獲取每一個列出的資源。這是個帶寬密集型的模式,但可以確保這些資源在請求時可用,即使瀏覽器正處于離線狀態(tài)。

lazy

lazy 不會預(yù)先緩存任何資源。相反,Angular Service Worker 只會緩存它收到請求的資源。這是一種按需緩存模式。永遠不會請求的資源也永遠不會被緩存。這對于像為不同分辨率提供的圖片之類的資源很有用,那樣 Service Worker 就只會為特定的屏幕和設(shè)備方向緩存正確的資源。

默認為 ?prefetch?。

updateMode

對于已經(jīng)存在于緩存中的資源,?updateMode ?會決定在發(fā)現(xiàn)了新版本應(yīng)用后的緩存行為。 自上一版本以來更改過的所有組中資源都會根據(jù) ?updateMode ?進行更新。

詳情

prefetch

要求 Service Worker 立即下載并緩存更新過的資源。

lazy

lazy 要求 Service Worker 不要緩存這些資源,而是先把它們看作未被請求的,等到它們再次被請求時才進行更新。lazy 這個 updateMode 只有在 installMode 也同樣是 lazy 時才有效。

其默認值為 ?installMode ?的值。

resources

本節(jié)描述要緩存的資源,分為如下幾組:

資源組

詳情

files

files 列出了與 dist 目錄中的文件相匹配的模式。它們可以是單個文件也可以是能匹配多個文件的類似 glob 的模式。

urls

包括要在運行時進行匹配的 URL 和 URL 模式。這些資源不是直接獲取的,也沒有內(nèi)容散列,但它們會根據(jù) HTTP 標(biāo)頭進行緩存。 這對于像 Google Fonts 服務(wù)這樣的 CDN 非常有用。
(不支持 glob 的逆模式,? 將會按字面匹配;也就是說它不會匹配除了 ? 之外的任何字符。)

cacheQueryOptions

這些選項用來修改對請求進行匹配的行為。它們會傳給瀏覽器的 ?Cache#match? 函數(shù)。詳情參閱 MDN。目前,只支持下列選項:

選項

詳情

ignoreSearch

忽略查詢參數(shù)。默認為 false。

dataGroups

與這些資產(chǎn)性(asset)資源不同,數(shù)據(jù)請求不會隨應(yīng)用一起版本化。它們會根據(jù)手動配置的策略進行緩存,這些策略對 API 請求和所依賴的其它數(shù)據(jù)等情況會更有用。

本字段包含一個數(shù)據(jù)組的數(shù)組,其中的每一個條目都定義了一組數(shù)據(jù)資源以及對它們的緩存策略。

{
  "dataGroups": [
    {
      …
    },
    {
      …
    }
  ]
}
當(dāng) ServiceWorker 處理請求時,它將按照數(shù)據(jù)組在 ?ngsw-config.json? 中出現(xiàn)的順序?qū)ζ溥M行檢查。與所請求的資源匹配的第一個數(shù)據(jù)組將處理該請求。
建議將更具體的數(shù)據(jù)組放在列表中較高的位置。比如,與 ?/api/foo.json? 匹配的數(shù)據(jù)組應(yīng)出現(xiàn)在與 ?/api/*.json? 匹配的數(shù)據(jù)組之前。

數(shù)據(jù)組遵循下列 TypeScript 接口:

export interface DataGroup {
  name: string;
  urls: string[];
  version?: number;
  cacheConfig: {
    maxSize: number;
    maxAge: string;
    timeout?: string;
    strategy?: 'freshness' | 'performance';
  };
  cacheQueryOptions?: {
    ignoreSearch?: boolean;
  };
}

name

和 ?assetGroups ?下類似,每個數(shù)據(jù)組也都有一個 ?name?,用作它的唯一標(biāo)識。

urls

一個 URL 模式的列表。匹配這些模式的 URL 將會根據(jù)該數(shù)據(jù)組的策略進行緩存。只有非修改型的請求(GET 和 HEAD)才會進行緩存。

  • 不支持 glob 中的否定模式
  • ??? 只做字面匹配,也就是說,它能匹配 ??? 字符。

version

API 有時可能會以不向后兼容的方式更改格式。新版本的應(yīng)用可能與舊的 API 格式不兼容,因此也就與該 API 中目前已緩存的資源不兼容。

?version ?提供了一種機制,用于指出這些被緩存的資源已經(jīng)通過不向后兼容的方式進行了更新,并且舊的緩存條目(即來自以前版本的緩存條目)應(yīng)該被丟棄。

?version ?是個整型字段,默認為 ?0?。

cacheConfig

本節(jié)定義了對匹配上的請求進行緩存時的策略。

maxSize

(必需)緩存的最大條目數(shù)或響應(yīng)數(shù)。開放式緩存可以無限增長,并最終超過存儲配額,建議適時清理。

maxAge

(必需)?maxAge ?參數(shù)表示在響應(yīng)因失效而要清除之前允許在緩存中留存的時間。?maxAge ?是一個表示持續(xù)時間的字符串,可使用以下單位作為后綴:

后綴

詳情

d

h

小時

m

分鐘

s

u

毫秒

比如,字符串 ?3d12h? 規(guī)定此內(nèi)容最多緩存三天半。

timeout

這個表示持續(xù)時間的字符串用于指定網(wǎng)絡(luò)超時時間。 如果配置了網(wǎng)絡(luò)超時時間,Angular Service Worker 就會先等待這么長時間再使用緩存。?timeout ?是一個表示持續(xù)時間的字符串,使用下列后綴單位:

后綴

詳情

d

h

小時

m

分鐘

s

u

毫秒

比如,字符串 ?5s30u? 將會被翻譯成 5 秒零 30 毫秒的網(wǎng)絡(luò)超時。

strategy

Angular Service Worker 可以使用兩種緩存策略之一來獲取數(shù)據(jù)資源。

緩存策略

詳情

performance

performance,默認值,為盡快給出響應(yīng)而優(yōu)化。如果緩存中存在某個資源,則使用這個緩存版本,而不再發(fā)起網(wǎng)絡(luò)請求。它允許資源有一定的陳舊性(取決于 maxAge)以換取更好的性能。適用于那些不經(jīng)常改變的資源,比如用戶頭像。

freshness

freshness 為數(shù)據(jù)的即時性而優(yōu)化,優(yōu)先從網(wǎng)絡(luò)獲取請求的數(shù)據(jù)。只有當(dāng)網(wǎng)絡(luò)超時時,請求才會根據(jù) timeout 的設(shè)置回退到緩存中。這對于那些頻繁變化的資源很有用,比如賬戶余額。

你還可以模擬第三種策略 staleWhileRevalidate,它會返回緩存的數(shù)據(jù)(如果可用),但是也會在后臺從網(wǎng)絡(luò)上獲取新數(shù)據(jù),以供下次使用。要使用本策略,請在 ?cacheConfig ?中把 ?strategy ?設(shè)置為 ?freshness?,并且把 ?timeout ?設(shè)置為 ?0u?。
本質(zhì)上說,它會做如下工作:
  1. 首先嘗試從網(wǎng)絡(luò)上獲取。
  2. 如果網(wǎng)絡(luò)請求沒有在 0ms 內(nèi)(也就是立刻)完成,就用緩存做為后備(忽略緩存有效期)。
  3. 一旦網(wǎng)絡(luò)請求完成,就更新緩存,以供將來的請求使用。
  4. 如果指定的資源在緩存中不存在,總是等待網(wǎng)絡(luò)請求。

cacheOpaqueResponses

Angular 服務(wù)工作者是否應(yīng)該緩存不透明的響應(yīng)。

如果未指定,則默認值取決于數(shù)據(jù)組的配置策略:

STRATEGIES

詳情

使用 freshness 策略的組

默認值為 true(緩存不透明響應(yīng))。這些組每次都會重新請求數(shù)據(jù),只有在脫機或在慢速網(wǎng)絡(luò)上時才會回到緩存響應(yīng)。因此,服務(wù)工作者是否緩存錯誤響應(yīng)是無關(guān)緊要的。

具有 performance 策略的組

默認值為 false(不緩存不透明響應(yīng))。這些組將繼續(xù)返回緩存響應(yīng),直到 maxAge 過期,即使錯誤是由于臨時網(wǎng)絡(luò)或服務(wù)器問題造成的。因此,服務(wù)工作者緩存錯誤響應(yīng)將是有問題的。

評論不透明的響應(yīng)
如果你不熟悉,不透明響應(yīng)是請求不同來源的不返回 CORS 標(biāo)頭的資源時返回的一種特殊類型的響應(yīng)。不透明響應(yīng)的特性之一是不允許服務(wù)工作者讀取其狀態(tài),這意味著它無法檢查請求是否成功。有關(guān)更多詳細信息,請參閱fetch()介紹。
如果你無法實現(xiàn) CORS(例如,如果你不控制來源),更愿意對會導(dǎo)致不透明響應(yīng)的資源使用 freshness 策略。

navigationUrls

這個可選節(jié)讓你可以指定一個自定義的 URL 列表,它們都會被重定向到索引文件。

處理導(dǎo)航請求

對于沒有匹配上任何 ?asset ?或 ?data ?組的導(dǎo)航請求,ServiceWorker 會把它們重定向到指定的索引文件。下列請求將會視為導(dǎo)航請求:

  • 它的模式是 ?navigation ?
  • 它接受 ?text/html? 響應(yīng)(根據(jù) ?Accept? 頭的值決定)
  • 它的 URL 符合特定的條件

默認情況下,這些條件是:

  • URL 的最后一段路徑中不能包含文件擴展名(比如 ?.?)
  • URL 中不能包含 ?__?

匹配導(dǎo)航請求的 URL

雖然這些默認條件在大多數(shù)情況下都挺好用,不過有時還是要配置一些不同的規(guī)則。比如,你可能希望忽略一些特定的路由(它們可能不是 Angular 應(yīng)用的一部分),而是把它們透傳給服務(wù)器。

該字段包含一個將要在運行期間匹配的 URL 和 類似 glob 的 URL 模式。 它既可以包含正向模式也可以包含反向模式(比如用 ?!? 開頭的模式)。

只有那些能匹配任意正向 URL 或 URL 模式并且不匹配任何一個反向模式的 URL 才會視為導(dǎo)航請求。當(dāng)匹配時,這些 URL 查詢將會被忽略。

如果省略了該字段,它的默認值是:

[
  '/**',           // Include all URLs.
  '!/**/*.*',      // Exclude URLs to files.
  '!/**/*__*',     // Exclude URLs containing `__` in the last segment.
  '!/**/*__*/**',  // Exclude URLs containing `__` in any other segment.
]

navigationRequestStrategy

通過此可選屬性,你可以配置服務(wù)工作者如何處理導(dǎo)航請求:

{
  "navigationRequestStrategy": "freshness"
}

可能的值

詳情

'performance'

默認設(shè)置。提供指定的索引文件,它通常會被緩存。

'freshness'

將請求透傳到網(wǎng)絡(luò),并在脫機時回退到 performance 模式。當(dāng)服務(wù)器在用 HTTP 重定向(3xx 狀態(tài)代碼)將導(dǎo)航請求重定向到其他位置時,此值很有用。使用此值的原因包括:

  • 當(dāng)應(yīng)用尚未處理身份驗證時,重定向到身份驗證網(wǎng)站。
  • 重定向特定的 URL,以免在網(wǎng)站重新設(shè)計后破壞現(xiàn)有的鏈接/書簽。
  • 當(dāng)頁面暫時關(guān)閉時,重定向到其他網(wǎng)站,比如服務(wù)器狀態(tài)頁。

?freshness ?策略通常會導(dǎo)致向服務(wù)器發(fā)送更多請求,這可能會增加響應(yīng)延遲。建議你盡可能使用默認的性能策略。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號