對(duì)下列知識(shí)有基本的了解:
配置文件 ?ngsw-config.json
? 指定了 Angular Service Worker 應(yīng)該緩存哪些文件和數(shù)據(jù)的 URL,以及如何更新緩存的文件和數(shù)據(jù)。?Angular CLI
? 會(huì)在 ?ng build
? 期間處理配置文件。如果想手動(dòng)處理,可以用 ?ngsw-config
? 工具(這里的 ?<project-name>
? 就是要構(gòu)建的項(xiàng)目名):
./node_modules/.bin/ngsw-config ./dist/<project-name> ./ngsw-config.json [/base/href]
該配置文件使用 JSON 格式。所有文件路徑都必須以 ?/
? 開頭,也就是相應(yīng)的部署目錄 —— 在 CLI 項(xiàng)目中的它通常是 ?dist/<project-name>
?。
除非另有注釋,否則模式使用limited* glob 格式,該格式將在內(nèi)部轉(zhuǎn)換為正則表達(dá)式:
GLOB 格式 |
詳情 |
---|---|
**
|
匹配 0 個(gè)或多個(gè)路徑段 |
*
|
匹配不包括 |
?
|
正好匹配不包括 |
|
將模式標(biāo)記為負(fù)數(shù),這意味著僅包含與模式不匹配的文件 |
請(qǐng)注意,在內(nèi)部 glob 到正則表達(dá)式的轉(zhuǎn)換中,正則表達(dá)式中某些具有特殊含義的字符不會(huì)被轉(zhuǎn)義,并且模式不會(huì)用 ?^
? / ?$
? 包裝。
- ?
$
? 是正則表達(dá)式中的一個(gè)特殊字符,它與字符串的結(jié)尾匹配,在將 glob 模式轉(zhuǎn)換為正則表達(dá)式時(shí)不會(huì)自動(dòng)轉(zhuǎn)義。如果你想從字面上匹配 ?$
? 字符,則必須自己對(duì)它進(jìn)行轉(zhuǎn)譯(使用 ?\\$
?)。例如,glob 模式 ?
/foo/bar/$value
? 會(huì)導(dǎo)致出現(xiàn)無(wú)法匹配的表達(dá)式,因?yàn)樽址豢赡茉诮Y(jié)尾后有任何字符。- 將模式轉(zhuǎn)換為正則表達(dá)式時(shí),不會(huì)自動(dòng)用 ?
^
? 和 ?$
? 包裝。因此,這些模式將部分匹配請(qǐng)求 URL。如果你希望你的模式匹配 URL 的開頭和/或結(jié)尾,可以自己添加 ?^
? / ?$
?。例如,glob 模式 ?
/foo/bar/*.js
? 將匹配 ?.js
? 和 ?.json
? 文件。如果你想僅匹配 ?.js
? 文件,請(qǐng)使用 ?/foo/bar/*.js$
?。
范例模式:
模式 |
詳情 |
---|---|
/**/*.html
|
指定所有 HTML 文件 |
/*.html
|
僅指定根中的 HTML 文件 |
!/**/*.map
|
排除所有源映射 |
下面講講配置文件中的每個(gè)屬性。
本節(jié)允許你傳遞用來(lái)描述這個(gè)特定應(yīng)用版本的任何數(shù)據(jù)。?SwUpdate
?服務(wù)會(huì)在更新通知中包含這些數(shù)據(jù)。許多應(yīng)用會(huì)使用本節(jié)來(lái)提供 UI 彈窗時(shí)要顯示的附加信息,以通知用戶有可用的更新。
指定用來(lái)充當(dāng)索引頁(yè)的文件以滿足導(dǎo)航請(qǐng)求。通常是 ?/index.html
?。
資產(chǎn)(Assets)是與應(yīng)用一起更新的應(yīng)用版本的一部分。它們可以包含從頁(yè)面的同源地址加載的資源以及從 CDN 和其它外部 URL 加載的第三方資源。由于在構(gòu)建時(shí)可能沒(méi)法提前知道所有這些外部 URL,因此也可以指定 URL 的模式。
該字段包含一個(gè)資產(chǎn)組的數(shù)組,每個(gè)資產(chǎn)組中會(huì)定義一組資產(chǎn)資源和它們的緩存策略。
{
"assetGroups": [
{
…
},
{
…
}
]
}
當(dāng) ServiceWorker 處理請(qǐng)求時(shí),它將按照資源組在 ?ngsw-config.json
? 中出現(xiàn)的順序?qū)ζ溥M(jìn)行檢查。與所請(qǐng)求的資源匹配的第一個(gè)資源組將處理該請(qǐng)求。
建議將更具體的資源組放在列表中較高的位置。比如,與 ?/foo.js
? 匹配的資源組應(yīng)出現(xiàn)在與 ?*.js
? 匹配的資源組之前。
每個(gè)資產(chǎn)組都會(huì)指定一組資源和一個(gè)管理它們的策略。此策略用來(lái)決定何時(shí)獲取資源以及當(dāng)檢測(cè)到更改時(shí)該怎么做。
這些資產(chǎn)組會(huì)遵循下面的 Typescript 接口:
interface AssetGroup {
name: string;
installMode?: 'prefetch' | 'lazy';
updateMode?: 'prefetch' | 'lazy';
resources: {
files?: string[];
urls?: string[];
};
cacheQueryOptions?: {
ignoreSearch?: boolean;
};
}
?name
?是強(qiáng)制性的。它用來(lái)標(biāo)識(shí)該配置文件版本中這個(gè)特定的資產(chǎn)組。
?installMode
?決定了這些資源最初的緩存方式。?installMode
?可以取如下兩個(gè)值之一:
值 |
詳情 |
---|---|
prefetch
|
要求 Angular Service Worker 在緩存當(dāng)前版本的應(yīng)用時(shí)要獲取每一個(gè)列出的資源。這是個(gè)帶寬密集型的模式,但可以確保這些資源在請(qǐng)求時(shí)可用,即使瀏覽器正處于離線狀態(tài)。 |
lazy
|
|
默認(rèn)為 ?prefetch
?。
對(duì)于已經(jīng)存在于緩存中的資源,?updateMode
?會(huì)決定在發(fā)現(xiàn)了新版本應(yīng)用后的緩存行為。 自上一版本以來(lái)更改過(guò)的所有組中資源都會(huì)根據(jù) ?updateMode
?進(jìn)行更新。
值 |
詳情 |
---|---|
prefetch
|
要求 Service Worker 立即下載并緩存更新過(guò)的資源。 |
lazy
|
|
其默認(rèn)值為 ?installMode
?的值。
本節(jié)描述要緩存的資源,分為如下幾組:
資源組 |
詳情 |
---|---|
files
|
|
urls
|
包括要在運(yùn)行時(shí)進(jìn)行匹配的 URL 和 URL 模式。這些資源不是直接獲取的,也沒(méi)有內(nèi)容散列,但它們會(huì)根據(jù) HTTP 標(biāo)頭進(jìn)行緩存。 這對(duì)于像 Google Fonts 服務(wù)這樣的 CDN 非常有用。
|
這些選項(xiàng)用來(lái)修改對(duì)請(qǐng)求進(jìn)行匹配的行為。它們會(huì)傳給瀏覽器的 ?Cache#match
? 函數(shù)。詳情參閱 MDN。目前,只支持下列選項(xiàng):
選項(xiàng) |
詳情 |
---|---|
ignoreSearch
|
忽略查詢參數(shù)。默認(rèn)為 |
與這些資產(chǎn)性(asset)資源不同,數(shù)據(jù)請(qǐng)求不會(huì)隨應(yīng)用一起版本化。它們會(huì)根據(jù)手動(dòng)配置的策略進(jìn)行緩存,這些策略對(duì) API 請(qǐng)求和所依賴的其它數(shù)據(jù)等情況會(huì)更有用。
本字段包含一個(gè)數(shù)據(jù)組的數(shù)組,其中的每一個(gè)條目都定義了一組數(shù)據(jù)資源以及對(duì)它們的緩存策略。
{
"dataGroups": [
{
…
},
{
…
}
]
}
當(dāng) ServiceWorker 處理請(qǐng)求時(shí),它將按照數(shù)據(jù)組在 ?ngsw-config.json
? 中出現(xiàn)的順序?qū)ζ溥M(jìn)行檢查。與所請(qǐng)求的資源匹配的第一個(gè)數(shù)據(jù)組將處理該請(qǐng)求。
建議將更具體的數(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;
};
}
和 ?assetGroups
?下類似,每個(gè)數(shù)據(jù)組也都有一個(gè) ?name
?,用作它的唯一標(biāo)識(shí)。
一個(gè) URL 模式的列表。匹配這些模式的 URL 將會(huì)根據(jù)該數(shù)據(jù)組的策略進(jìn)行緩存。只有非修改型的請(qǐng)求(GET 和 HEAD)才會(huì)進(jìn)行緩存。
?
? 只做字面匹配,也就是說(shuō),它只能匹配 ??
? 字符。API 有時(shí)可能會(huì)以不向后兼容的方式更改格式。新版本的應(yīng)用可能與舊的 API 格式不兼容,因此也就與該 API 中目前已緩存的資源不兼容。
?version
?提供了一種機(jī)制,用于指出這些被緩存的資源已經(jīng)通過(guò)不向后兼容的方式進(jìn)行了更新,并且舊的緩存條目(即來(lái)自以前版本的緩存條目)應(yīng)該被丟棄。
?version
?是個(gè)整型字段,默認(rèn)為 ?0
?。
本節(jié)定義了對(duì)匹配上的請(qǐng)求進(jìn)行緩存時(shí)的策略。
(必需)緩存的最大條目數(shù)或響應(yīng)數(shù)。開放式緩存可以無(wú)限增長(zhǎng),并最終超過(guò)存儲(chǔ)配額,建議適時(shí)清理。
(必需)?maxAge
?參數(shù)表示在響應(yīng)因失效而要清除之前允許在緩存中留存的時(shí)間。?maxAge
?是一個(gè)表示持續(xù)時(shí)間的字符串,可使用以下單位作為后綴:
后綴 |
詳情 |
---|---|
d
|
天 |
h
|
小時(shí) |
m
|
分鐘 |
s
|
秒 |
u
|
毫秒 |
比如,字符串 ?3d12h
? 規(guī)定此內(nèi)容最多緩存三天半。
這個(gè)表示持續(xù)時(shí)間的字符串用于指定網(wǎng)絡(luò)超時(shí)時(shí)間。 如果配置了網(wǎng)絡(luò)超時(shí)時(shí)間,Angular Service Worker 就會(huì)先等待這么長(zhǎng)時(shí)間再使用緩存。?timeout
?是一個(gè)表示持續(xù)時(shí)間的字符串,使用下列后綴單位:
后綴 |
詳情 |
---|---|
d
|
天 |
h
|
小時(shí) |
m
|
分鐘 |
s
|
秒 |
u
|
毫秒 |
比如,字符串 ?5s30u
? 將會(huì)被翻譯成 5 秒零 30 毫秒的網(wǎng)絡(luò)超時(shí)。
Angular Service Worker 可以使用兩種緩存策略之一來(lái)獲取數(shù)據(jù)資源。
緩存策略 |
詳情 |
---|---|
performance
|
|
freshness
|
|
你還可以模擬第三種策略 staleWhileRevalidate,它會(huì)返回緩存的數(shù)據(jù)(如果可用),但是也會(huì)在后臺(tái)從網(wǎng)絡(luò)上獲取新數(shù)據(jù),以供下次使用。要使用本策略,請(qǐng)?jiān)?nbsp;?cacheConfig
?中把 ?strategy
?設(shè)置為 ?freshness
?,并且把 ?timeout
?設(shè)置為 ?0u
?。
本質(zhì)上說(shuō),它會(huì)做如下工作:
- 首先嘗試從網(wǎng)絡(luò)上獲取。
- 如果網(wǎng)絡(luò)請(qǐng)求沒(méi)有在 0ms 內(nèi)(也就是立刻)完成,就用緩存做為后備(忽略緩存有效期)。
- 一旦網(wǎng)絡(luò)請(qǐng)求完成,就更新緩存,以供將來(lái)的請(qǐng)求使用。
- 如果指定的資源在緩存中不存在,總是等待網(wǎng)絡(luò)請(qǐng)求。
Angular 服務(wù)工作者是否應(yīng)該緩存不透明的響應(yīng)。
如果未指定,則默認(rèn)值取決于數(shù)據(jù)組的配置策略:
STRATEGIES |
詳情 |
---|---|
使用 |
默認(rèn)值為 |
具有 |
默認(rèn)值為 |
評(píng)論不透明的響應(yīng)
如果你不熟悉,不透明響應(yīng)是請(qǐng)求不同來(lái)源的不返回 CORS 標(biāo)頭的資源時(shí)返回的一種特殊類型的響應(yīng)。不透明響應(yīng)的特性之一是不允許服務(wù)工作者讀取其狀態(tài),這意味著它無(wú)法檢查請(qǐng)求是否成功。有關(guān)更多詳細(xì)信息,請(qǐng)參閱fetch()介紹。
如果你無(wú)法實(shí)現(xiàn) CORS(例如,如果你不控制來(lái)源),更愿意對(duì)會(huì)導(dǎo)致不透明響應(yīng)的資源使用 freshness 策略。
這個(gè)可選節(jié)讓你可以指定一個(gè)自定義的 URL 列表,它們都會(huì)被重定向到索引文件。
對(duì)于沒(méi)有匹配上任何 ?asset
?或 ?data
?組的導(dǎo)航請(qǐng)求,ServiceWorker 會(huì)把它們重定向到指定的索引文件。下列請(qǐng)求將會(huì)視為導(dǎo)航請(qǐng)求:
navigation
?text/html
? 響應(yīng)(根據(jù) ?Accept
? 頭的值決定)默認(rèn)情況下,這些條件是:
.
?)__
?雖然這些默認(rèn)條件在大多數(shù)情況下都挺好用,不過(guò)有時(shí)還是要配置一些不同的規(guī)則。比如,你可能希望忽略一些特定的路由(它們可能不是 Angular 應(yīng)用的一部分),而是把它們透?jìng)鹘o服務(wù)器。
該字段包含一個(gè)將要在運(yùn)行期間匹配的 URL 和 類似 glob 的 URL 模式。 它既可以包含正向模式也可以包含反向模式(比如用 ?!
? 開頭的模式)。
只有那些能匹配任意正向 URL 或 URL 模式并且不匹配任何一個(gè)反向模式的 URL 才會(huì)視為導(dǎo)航請(qǐng)求。當(dāng)匹配時(shí),這些 URL 查詢將會(huì)被忽略。
如果省略了該字段,它的默認(rèn)值是:
[
'/**', // Include all URLs.
'!/**/*.*', // Exclude URLs to files.
'!/**/*__*', // Exclude URLs containing `__` in the last segment.
'!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
]
通過(guò)此可選屬性,你可以配置服務(wù)工作者如何處理導(dǎo)航請(qǐng)求:
{
"navigationRequestStrategy": "freshness"
}
可能的值 |
詳情 |
---|---|
'performance'
|
默認(rèn)設(shè)置。提供指定的索引文件,它通常會(huì)被緩存。 |
'freshness'
|
將請(qǐng)求透?jìng)鞯骄W(wǎng)絡(luò),并在脫機(jī)時(shí)回退到
|
?
freshness
?策略通常會(huì)導(dǎo)致向服務(wù)器發(fā)送更多請(qǐng)求,這可能會(huì)增加響應(yīng)延遲。建議你盡可能使用默認(rèn)的性能策略。
更多建議: