如何避免 Angular 被瀏覽器 cache ?
瀏覽器為了效能,會對 HTML、JavaScript 與 CSS 做 cache,其本意是好的,但對於 developer 來說,卻擔心更新到 production server 後,user 仍然是執行到被瀏覽器 cache 的 HTML、JavaScript 與 CSS,Angular 該如何解決這個問題呢 ?
Version
Angular 5.1
HTML
在經過 Angular CLI 的 ng build --prod
之後,會在 dist
目錄下產生整個 Angular 專案唯一的 index.html
,擔心的是 user 執行到被瀏覽器 cache 的 index.html
。
新增 HTML Meta
src/index.html
1 | <!doctype html> |
第 6 行1
2
3<meta http-equiv="Cache-Control" content="no-cache, no-store, max-age=0, must-revalidate">
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="expires" content="0" />
新增這 3 行 <meta>
。
在 HTTP 1.1 規格中,有 Cache-Control 可設定瀏覽器的 cache。
在 HTTP 1.0 規格中,有 Pragma 可設定瀏覽器的 cache。
而 HTTP 1.0 與 1.1 都有 Expires
設定 cache 內容的有效期限,但在 1.1 的規格中,Cache-Control
的優先權是大於 Expires
,因此可以規劃出以上通用設定,就可避免 index.html
被瀏覽器 cache。
- 開啟
src
目錄下的index.html
- 加入 3 行
<meta>
編譯 Angular
1 | ~/MyProject $ ng build --prod |
要放進 production server 的 code,最後會加上 --prod
。
編譯後的 index.html
經過 ng build --prod
之後的 HTML、JavaScript 與 CSS 都會放在 dist
目錄下。
- 選擇
dist
目錄 - 選擇
index.html
,這是最後會上 production server 的index.html
- 我們剛剛加入的 3 個
<meta>
都還留著,因此不用每次編譯就修改index.html
只要改一次
src/index.html
的<meta>
,之後就不用擔心 HTML 被瀏覽器 cache 的問題
JavaScript
JavaScript 若檔名相同,瀏覽器會優先選擇使用本地的 cache 增加效能,Angular CLI 在每次 ng build --prod
之後,會重新以亂數命名 JavaScript 檔案,因此瀏覽器只能重新對 server 抓 *.js
,而不會採用瀏覽器的 cache。
所有經過 ng build --prod
所 bundle 的 JavaScript 都經過亂數改掉檔名,因此瀏覽器一定會再跟 server 要新的 JavaScript。
Angular CLI 會幫我們將所引用的 JavaScript 一併改名。
CSS
CSS 若檔名相同,瀏覽器會優先選擇使用本地的 cache 增加效能,Angular CLI 在每次 ng build --prod
之後,會重新以亂數命名 CSS 檔案,因此瀏覽器只能重新對 server 抓 *.css
,而不會採用瀏覽器的 cache。
所有經過 ng build --prod
所 bundle 的 CSS 都經過亂數改掉檔名,因此瀏覽器一定會再跟 server 要新的 CSS。
Angular CLI 會幫我們將所引用的 CSS 一併改名。
Conclusion
- 在開發階段時,完全不用擔心 HTML、JavaScript 與 CSS 被瀏覽器 cache 問題,Angular CLI 內建的 web server 已經幫我們處理
- 由於 JavaScript 並沒有提供
<meta>
機制,因此若將 JavaScript 獨立於 HTML,就必須面臨 JavaScript 可能被瀏覽器 cache 的問題,Angular CLI 已經幫我們處理了 JavaScript 與 CSS,我們唯一需要處理的只剩下 HTML 部分,所幸 HTML 部分可簡單的用<meta>
處理即可