<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端性能優(yōu)化-開啟 HTTP 緩存

          共 18950字,需瀏覽 38分鐘

           ·

          2024-12-03 22:37

          本文適合對開啟HTTP緩存是前端性能優(yōu)化感興趣的小伙伴閱讀。

          歡迎關(guān)注前端早茶,與廣東靚仔攜手共同進階~


          前言

          開啟HTTP緩存是前端性能優(yōu)化中提高資源加載效率的重要手段。以下是幾個關(guān)鍵點:

          1. 減少重復請求:通過緩存機制,瀏覽器可以存儲已請求過的資源,減少對服務器的重復請求。

          2. 設(shè)置緩存頭:在服務器端設(shè)置合適的Cache-Control、ExpiresETag響應頭,告訴瀏覽器如何緩存資源。

          3. 區(qū)分靜態(tài)和動態(tài)資源:靜態(tài)資源(如圖片、CSS、JS文件)可以設(shè)置較長的緩存時間,而動態(tài)內(nèi)容則需要更短的緩存時間或使用驗證緩存。

          4. 利用瀏覽器緩存:合理配置服務端緩存策略,讓瀏覽器自動處理緩存,減少不必要的網(wǎng)絡請求。

          5. 更新緩存策略:當資源更新時,確保使用新的緩存策略,如改變文件名或使用Last-ModifiedETag頭來驗證緩存。

          6. 監(jiān)控緩存效果:使用瀏覽器的開發(fā)者工具監(jiān)控資源的緩存情況,確保緩存策略按預期工作。

          通過開啟HTTP緩存,可以顯著減少頁面加載時間,提升用戶體驗。

          導讀

          開啟 HTTP 緩存是前端性能優(yōu)化手段中最常見的方法之一。開啟 HTTP 緩存后,當瀏覽器請求資源時,提供資源的服務器可以告知瀏覽器應該臨時存儲或緩存該資源多長時間。

          只要資源的緩存沒有過期,對于針對該資源的任何后續(xù)請求,瀏覽器將使用其本地副本,而不是從網(wǎng)絡獲取。也就有效的減少了 HTTP 請求,可以顯著地縮短重復訪問的網(wǎng)頁加載時間。

          正文

          NGINX 服務器端配置 HTTP 緩存

          與啟用 Gzip 壓縮實現(xiàn)手段類似,開啟 HTTP 緩存的操作也是在服務器端配置實現(xiàn)。本文還是以 NGINX 服務器為例,介紹如何在 NGINX 服務器配置 HTTP 緩存。

          開啟 HTTP 緩存的實際操作配置就是配置 Expires 頭,并且盡量設(shè)置一個長久的 Expires。用 lighthouse 官方文檔的說法是:采用高效的緩存政策提供靜態(tài)資源。 來看看 NGINX 服務器的配置吧:

          cache_expiration.conf

          與配置 gzip 時一樣,緩存的配置信息,也建議單獨保存到獨立的配置文件。然后使用 include 在 nginx.conf 文件中引用配置。

          http {
            # 其它配置
            
            # Specify file cache expiration.
            include web_performance/cache_expiration.conf;
          }

          在 nginx.conf 的 http 模塊中引入cache_expiration.conf 文件的緩存配置,這樣只要是通過當前 NGINX 服務配置的 Web 站點也就都開啟了 HTTP 緩存了。

          cache_expiration.conf 配置信息如下:

          map $sent_http_content_type $expires {
          default 1M;

          # No content
          '' off;

          # CSS
          ~*text/css 1y;

          # Data interchange
          ~*application/atom\+xml 1h;
          ~*application/rdf\+xml 1h;
          ~*application/rss\+xml 1h;

          ~*application/json 0;
          ~*application/ld\+json 0;
          ~*application/schema\+json 0;
          ~*application/geo\+json 0;
          ~*application/xml 0;
          ~*text/calendar 0;
          ~*text/xml 0;

          # Favicon (cannot be renamed!) and cursor images
          ~*image/vnd.microsoft.icon 1w;
          ~*image/x-icon 1w;

          # HTML
          ~*text/html 0;

          # JavaScript
          ~*application/javascript 1y;
          ~*application/x-javascript 1y;
          ~*text/javascript 1y;

          # Manifest files
          ~*application/manifest\+json 1w;
          ~*application/x-web-app-manifest\+json 0;
          ~*text/cache-manifest 0;

          # Markdown
          ~*text/markdown 0;

          # Media files
          ~*audio/ 1M;
          ~*image/ 1M;
          ~*video/ 1M;

          # WebAssembly
          ~*application/wasm 1y;

          # Web fonts
          ~*font/ 1M;
          ~*application/vnd.ms-fontobject 1M;
          ~*application/x-font-ttf 1M;
          ~*application/x-font-woff 1M;
          ~*application/font-woff 1M;
          ~*application/font-woff2 1M;

          # Other
          ~*text/x-cross-domain-policy 1w;
          }

          # 時間根據(jù)變量 $expires 的配置匹配
          expires $expires;

          緩存哪些資源,緩存多久?

          這個 cache_expiration.conf 文件的配置可能要比大家通??吹降呐渲靡獜碗s一些,不過應該也是很容易看懂的。其主要策略就是針對不會經(jīng)常調(diào)整的文件類型,盡量給一個長久的 Expires。

          另外,通過 cache_expiration.conf 配置文件的內(nèi)容,也可以明確的發(fā)現(xiàn),緩存的基本上都是靜態(tài)資源,并且不同的靜態(tài)資源緩存的時長是不一樣的。

          例如 .css 和 .js 文件,這里的配置就給了 1y(一年),字體和圖片資源也設(shè)置了 1M(一個月),而經(jīng)常請求的 json 數(shù)據(jù)則沒有緩存。$expires 變量會根據(jù)不同的資源類型,定義不同的合適的緩存時間。

          Lighthouse 的緩存策略

          再看看前端性能分析工具 Lighthouse。如果滿足以下所有條件,則 Lighthouse 會認為資源可緩存:

          • 資源可以是字體、圖片、媒體文件、腳本或樣式表。
          • 資源具有 200、203 或 206 HTTP 狀態(tài)代碼[1]。
          • 資源沒有明確的無緩存政策。

          cache-control.conf

          除了配置 Expires 頭的配置,另外一個重要配置就是 cache-control.conf 文件。cache-control.conf 文件中就是針對 Cache-Control 首部字段的配置:

          map $sent_http_content_type $cache_control {
              default                           'public, immutable, stale-while-revalidate';

              # No content
              ''                                'no-store';

              # Manifest files
              ~*application/manifest\+json      'public';
              ~*text/cache-manifest             ''# `no-cache` (*)

              # Assets
              ~*image/svg\+xml                  'public, immutable, stale-while-revalidate';

              # Data interchange
              ~*application/(atom|rdf|rss)\+xml 'public, stale-while-revalidate';

              # Documents
              ~*text/html                       'private, must-revalidate';
              ~*text/markdown                   'private, must-revalidate';
              ~*text/calendar                   'private, must-revalidate';

              # Data
              ~*json                            ''# `no-cache` (*)
              ~*xml                             ''# `no-cache` (*)
          }

          也是在 nginx.conf 的 http 模塊中引入:

          http {
              # 省略其它配置...
              
              # Add Cache-Control.
              include web_performance/cache-control.conf;
          }

          跟 Expires 的配置類似,$cache_control 變量在此 NGINX 配置的所有 Web 站點就都可以訪問該變量了。Cache-Control 中可用的指令在稍后的介紹 Cache-Control 首部字段章節(jié)會詳細介紹。

          與緩存相關(guān)的 HTTP 首部字段

          HTTP 緩存配置完畢后,在我們請求的靜態(tài)資源的服務器響應頭中就可以看到 Expires 首部字段信息了:

          大家可以根據(jù)自己的情況調(diào)整這里的配置,確定不怎么變動的資源,還是盡量給一個長久的 Expires。需要說明一下,HTML 頁面通常視作動態(tài)資源,建議是不要設(shè)置 Expires 頭的(稍后的章節(jié)中有示例會給出針對 HTML 頁面的配置細節(jié))。

          因為如果 HTML 文件緩存了,緩存期間不更新,那么我們在指定時間內(nèi)永遠沒法取到更新后的 js 和 css 或者其它靜態(tài)資源。所以,HTML 緩存另一個策略是:不緩存html

            # HTML
            ~*text/html                             0;

          另外,如果不希望配置一個全局的靜態(tài)資源的 Expires 頭,可以去掉cache_expiration.conf文件最底部的配置:

          # expires $expires

          調(diào)整后,在 nginx.conf 配置文件中引入的就只是針對不同靜態(tài)文件過期時間變量 $expires 的配置。這樣就不會出現(xiàn) NGINX 服務器上所有配置的所有 Web 站點都使用相同的 Expires 頭的緩存配置,但又都可以訪問 $expires 變量了。

          到這里,關(guān)于在 NGINX 服務配置 HTTP 緩存的操作內(nèi)容就結(jié)束了。是不是很容易?

          Cache-Control 和 Expires 首部字段

          在解釋緩存如何很好的優(yōu)化靜態(tài)資源傳輸速度前,需要跟大家聊聊 2 個 HTTP 首部字段 - Cache-Control 和 Expires。

          Expires 首部字段

          由于 Expires 頭使用一個特定時間:

          Wed, 23 Jul 2025 12:37:27 GMT

          這使得 Expires 頭有一定的局限性,因為 Expires 頭要求服務器和客戶端的時間要嚴格同步。如果本地電腦調(diào)整了時間,超過了 Exipres 頭設(shè)置的時間,也會使緩存過期。

          另外,Exipres 頭會經(jīng)常檢測過期時間,并且一旦過期了,又需要再服務器中配置提供一個新的日期。所以會有 Exipres 頭設(shè)置的時間盡量長的策略。

          Cache-Control 首部字段

          為解決 Exipres 頭的這些不足,HTTP 1.1 協(xié)議中引入了 Cache-Control 首部字段。Cache-Control 使用 max-age 指令指定組件被緩存多久。它以秒為單位定義更新時間。如果從資源被請求開始過去的秒數(shù)小于 max-age,瀏覽器就會使用緩存版本。它可以消除 Expires 頭對于服務器和客戶端的時間必須同步的限制。對于不支持 Cache-Control 首部字段的瀏覽器,我們?nèi)匀恍枰?Expires 頭,因此一般都會同時設(shè)置 Cache-Control 和 Expires 首部字段。在支持 Cache-Control 頭的瀏覽器,max-age 指定將重寫 Expires 頭。這也是為什么前文的截圖中同時出現(xiàn)了 Cache-Control 和 Expires 首部字段的響應信息。

          max-age 指定的設(shè)置策略也和 Expires 頭一致,盡量設(shè)置一個較長的時間。最大可以設(shè)置 10 年,一般都設(shè)置至少 30 天以上。

          注意: 緩存持續(xù)時間過長的一個風險就是您的用戶不會看到靜態(tài)文件的更新。若要避免此問題,可以將構(gòu)建工具配置為在靜態(tài)資源文件名中嵌入一個哈希,以使每個版本都是唯一的,從而提示瀏覽器從服務器提取新版本。

          Cache-Control 首部字段常用指令

          除 max-age 指定外,其它常用的指令還有:

          • public:表明響應可以被任何對象(包括:發(fā)送請求的客戶端,代理服務器,等等)緩存。表示相應會被緩存,并且在多用戶間共享。默認是 public。
          • private:表明響應只能被單個用戶緩存,不能作為共享緩存(即代理服務器不能緩存它),可以緩存響應內(nèi)容。響應只作為私有的緩存,不能在用戶間共享。如果要求HTTP認證,響應會自動設(shè)置為private。
          • no-cache:在釋放緩存副本之前,強制高速緩存將請求提交給原始服務器進行驗證。指定不緩存響應,表明資源不進行緩存。但是設(shè)置了no-cache之后并不代表瀏覽器不緩存,而是在緩存前要向服務器確認資源是否被更改。因此有的時候只設(shè)置no-cache防止緩存還是不夠保險,還可以加上private指令,將過期時間設(shè)為過去的時間。
          • only-if-cached:表明客戶端只接受已緩存的響應,并且不要向原始服務器檢查是否有更新的拷貝.
          • no-store:緩存不應存儲有關(guān)客戶端請求或服務器響應的任何內(nèi)容。表示絕對禁止緩存!
          • no-transform:不得對資源進行轉(zhuǎn)換或轉(zhuǎn)變。Content-Encoding, Content-Range, Content-Type 等 HTTP 頭不能由代理修改。例如,非透明代理可以對圖像格式進行轉(zhuǎn)換,以便節(jié)省緩存空間或者減少緩慢鏈路上的流量。no-transform 指令不允許這樣做。

          例如我本地的測試站點,針對 HTML 頁面的配置就使用了 no-cache:

          location / {
          proxy_pass http://yao;
          proxy_http_version 1.1;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          # 省略其它配置...

          # 不緩存 index.html
          expires -1;
          add_header Cache-Control no-store;

          # fix history router model in VUE
          try_files $uri $uri/ /index.html;
          error_page 404 /index.html;
          }

          說明一下,一直在介紹設(shè)置 Expires 頭,卻沒有介紹如何配置 Cache-Control 頭,直到示例中才展示的設(shè)置 no-store。這是因為在 NGINX 服務器中配置了 Expires 頭,在配置反向代理指定了 HTTP1.1 協(xié)議后:

          proxy_http_version 1.1;

          NGINX 服務器會使用 Cache-Control 頭重寫 Expires 頭,過期時間就是 Expires 頭配置的時間。因此如果不是像 HTML 文件這樣需要禁止緩存,沒有額外的 Cache-Control 頭配置。

          再以前文的截圖為例,這里獲取到的 js 文件的 max-age 指令的時長就和 Expires 頭的過期時間一致。

          如果資源變化和新鮮度很重要,但仍想獲得緩存的一些速度優(yōu)勢,請使用 no-cache瀏覽器仍會緩存設(shè)置為 no-cache 的資源,但會先向服務器進行檢查,以確保該資源仍為最新資源。

          前文介紹了 Cache-Control 頭允許使用的許多不同的指令,它們可用于自定義瀏覽器如何緩存不同資源,請根據(jù)需要選擇選擇合適的 Cache-Control 頭指令。

          最后要特別說明,雖然介紹的 Expires 頭和 Cache-Control 頭的 max-age 指令中推薦的策略是盡可能長,但緩存時間不一定是越長越好。最終還是應該根據(jù)實際使用情況來決定資源的最佳緩存時長。

          Last-Modified Date 和 ETag

          Cache-Control 和 Expires 兩個 HTTP 首部字段是用來指定資源的緩存時長的。而服務器在檢測緩存的資源是否和原始服務器上的資源匹配,則使用的是另外 2 種方式:

          • 比較最新修改日期(Last-Modified Date)
          • 比較實體標簽(ETag)
          最新修改時間(Last-Modified Date)

          原始服務器通過 Last-Modified 響應頭來返回組件的最新修改日期:

          Last-Modified: Tue, 25 Jun 2024 20:20:53 GMT

          設(shè)置了 Expires 頭后,瀏覽器會緩存資源和它的最新修改日期。再次請求同一資源時,瀏覽器會使用 If-Modified-Since 頭將最新修改日期回傳到原始服務器進行比較。如果匹配則返回 304 響應,而不會重新下載組件。

          實體標簽(ETag)

          實體標簽 ETag 是 Web 服務器和瀏覽器用于確認緩存資源的有效性的一種機制。ETag 在 HTTP 1.1 引入,它是表示組件的特定版本的唯一性的字符串。例如:

          Etag: 'b886a62d3dc7da1:0'

          它是提供了另一種方式檢測緩存的資源是否與原始服務器上的資源是否匹配。ETag 的檢測機制要比最新修改時間更加靈活。例如,如果實體依據(jù) User-Agent 或者 Accept-Language 頭而改變,實體的狀態(tài)可以反應在 ETag 中。也就是說 ETag 的唯一字符串的值會發(fā)生改變。

          ETag 的驗證機制是在次訪問同一資源的時候,它會使用 If-None-Match 頭將 ETag 傳回原服務器。如果匹配則返回 304 響應,而不會重新下載資源。

          ETag 的問題

          通常的 Web 服務器的架構(gòu)設(shè)計都是做了高可用的配置的,是由多臺服務器組成的集群構(gòu)建而成。例如我本地的測試站點的負載均衡的配置:

          upstream yao {
            server 127.0.0.1:18080;
            server 127.0.0.1:18081;
            server 127.0.0.1:18082;
          }

          ETag 有個問題,當瀏覽器分別從兩臺不同的后端集群服務器中請求同一資源的時候,兩臺不同的服務器的 ETag 是不會一致的。

          當然,我們可以通過在負載平衡的配置中添加 keepalive 或者設(shè)置服務器的 weight 權(quán)重,讓同一客戶端盡量從同一服務器獲取資源,但還是無法保證會切換服務器請求資源。

          NGINX 配置反向代理緩存

          既然提到了服務器組成的集群,除了使用普通的靜態(tài)資源的 HTTP 緩存外,我們還可以將服務器集群中的原始資源緩存到代理服務器上,也就是配置反向代理緩存,將資源都緩存到 NGINX 服務器所在的代理服務器上。

          如圖所示,用戶第一次請求資源,NGINX 服務器會向集群中的服務器請求資源,然后緩存下來。用戶再次請求數(shù)據(jù)的時候,如果 NGINX 服務器已經(jīng)緩存了,NGINX 服務器就會直接響應,而不用再向上游的服務器集群的服務器請求資源了。這樣就進一步優(yōu)化了請求的響應速度,也更進一步的優(yōu)化了前端性能。

          配置反向代理緩存

          要配置反向代理緩存,需要在 NGINX 服務器上配置一個緩存區(qū)域,指定緩存路徑,目錄層級,共享內(nèi)存的大小等信息。廢話不多說,直接上配置文件。

          proxy_cache_path 指令

          proxy_cache_path 是 Nginx 中用于配置反向代理緩存的指令。它定義了緩存存儲的位置、緩存大小、緩存的各種參數(shù)等。反向代理緩存可以極大地提高性能,減少對后端服務器的負載。

          還是老規(guī)矩,使用獨立的 proxy_cache.conf 文件保存 proxy_cache_path 配置,然后在需要的地方 include 配置;

          proxy_cache_path  ./cache
          levels=1:2
          keys_zone=cache_static:100m
          inactive=1h
          max_size=300m
          use_temp_path=off;
          • proxy_temp_path=./cache: 緩存臨時目錄路徑;
          • levels=1:2: 緩存目錄地層級,默認所有緩存文件都放在同一個目錄下,從而影響緩存的性能,大部分場景推薦使用2級目錄來存儲緩存文件;
          • keys_zone=cache_static:100m: 在共享內(nèi)存中設(shè)置一塊存儲區(qū)域來存放緩存的 key 和 metadata(類似使用次數(shù)),這樣 nginx 可以快速判斷一個 request 是否命中或者未命中緩存,1m 可以存儲 8000 個 key,100m 可以存儲 800000 個 key;
          • max_size=300m: 最大 cache 空間,如果不指定,會使用掉所有磁盤空間(disk space),當達到配額后,會刪除最少使用的 cache 文件;
          • inactive=1d: 未被訪問文件在緩存中保留時間,本配置中如果 60 分鐘未被訪問則不論狀態(tài)是否為 expired,緩存控制程序會刪掉文件,默認為10分鐘;需要注意的是,inactive 和 expired 配置項的含義是不同的,expired 只是緩存過期,但不會被刪除,inactive 是刪除指定時間內(nèi)未被訪問的緩存文件;
          • use_temp_path=off: 如果為 off,則 nginx 會將緩存文件直接寫入指定的 cache 文件中,而不是使用 temp_path 存儲,official 建議為 off,避免文件在不同文件系統(tǒng)中不必要的拷貝;
          nginx.conf 引用代理緩存配置

          proxy_cache_path 是一個全局性的配置,通常會在 nginx.conf 配置文件中使用 include 方式引入配置:

          http {
            # 省略其它配置...
            
            # 代理緩存配置
            include web_performance/proxy_cache.conf;
          }

          這樣只要是此 NGINX 服務配置的 Web 站點,就都可以引用 proxy_cache.conf 的代理緩存配置了。

          為 Web 站點的靜態(tài)資源配置反向代理緩存

          通常我們都是緩存靜態(tài)資源,所以這里就以我本地的測試站點的靜態(tài)資源的配置作為示例:

          # 上游的服務器負載均衡配置
          include upstreams/www.yao.com.conf;

          server {
          listen [::]:80;
          listen 80;
          server_name www.yao.com;

          # 將 http 請求訪問,跳轉(zhuǎn)到相應的 https 訪問路徑
          return 301 https://$host$request_uri;
          }

          server {
          # 下次介紹配置 HTTPS 和 HTTP2
          # listen [::]:443 ssl http2;
          listen 443 ssl http2;

          server_name www.yao.com;

          # 配置證書信息
          include ssl/ssl_engine.conf;
          include ssl/default_certificate_files.conf;
          include ssl/policy_intermediate.conf;

          # 針對首頁的配置
          location / {
          proxy_pass http://yao;
          proxy_http_version 1.1;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          proxy_intercept_errors on;

          proxy_next_upstream error timeout invalid_header http_500;
          proxy_connect_timeout 2;

          add_header X-Upstream $upstream_addr;
          proxy_pass_header Authorization;

          client_body_in_file_only clean;
          client_body_buffer_size 32K;
          client_max_body_size 150M;

          # 不緩存 index.html
          expires -1;
          add_header Cache-Control no-store;

          # fix history router model in VUE
          try_files $uri $uri/ /index.html;
          error_page 404 /index.html;
          }

          # 訪問前端站點的靜態(tài)文件的代理配置
          # 根據(jù)自己的需要添加靜態(tài)資源的后綴名
          location ~* \.(js|css)$ {
          proxy_pass http://yao;

          # 通用的一些反向代理配置
          proxy_http_version 1.1;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          # 設(shè)置資源緩存的 zone,使用之前配置的 cache_static
          proxy_cache cache_static;
          # 設(shè)置緩存的 key
          proxy_cache_key $host$uri$is_args$args;
          # 設(shè)置狀態(tài)碼為 200 和 304 的響應可以進行緩存,并且緩存時間為 10 分鐘
          # 根據(jù)自己的站點情況配置時長,時間臺長 cache_static 空間很快會消耗完
          proxy_cache_valid 200 304 10m;

          # 調(diào)整原服務器的緩存配置
          proxy_ignore_headers Expires Set-Cookie Cache-Control;
          proxy_hide_header Cache-Control;
          proxy_hide_header Set-Cookie;
          # 調(diào)整原服務器的 Accept-Encoding
          proxy_set_header Accept-Encoding 'gzip';

          # 被多次用到的資源才緩存,只用一次的無需代理緩存
          proxy_cache_min_uses 2;
          # 配置自定義頭 X-Cache 顯示代理緩存命中狀態(tài)
          add_header X-Cache $upstream_cache_status;

          # 根據(jù)之前的 $expires 匹配的資源文件類型設(shè)置過期時間
          # 當然,你也可以自己根據(jù)需要,直接設(shè)置一個合適的過期時間
          expires $expires;
          add_header Cache-Control 'public, no-transform';
          }
          }
          $upstream_cache_status 變量監(jiān)測代理緩存狀態(tài)

          NGINX 提供了 $upstream_cache_status 這個變量來顯示緩存的狀態(tài).在這里的配置中添加了一個自定義的 X-Cache 頭,使用 $upstream_cache_status 監(jiān)測代理緩存的狀態(tài)。以下是 $upstream_cache_status 的可能值:

          • MISS - 在緩存中找不到響應,因此從原始服務器獲取。然后可以緩存響應;
          • BYPASS - 響應是從原始服務器獲取的,而不是從緩存中提供的,因為請求與proxy_cache_bypass指令匹配(請參閱下面的“我可以通過我的緩存打孔嗎?”)然后可以緩存響應;
          • EXPIRED - 緩存中的條目已過期。響應包含來自源服務器的新內(nèi)容;
          • STALE - 內(nèi)容過時,因為原始服務器未正確響應,并且已配置proxy_cache_use_stale;
          • UPDATING- 內(nèi)容過時,因為當前正在更新條目以響應先前的請求,并且配置了proxy_cache_use_stale更新;
          • REVALIDATED - 啟用了proxy_cache_revalidate指令,NGINX驗證當前緩存的內(nèi)容仍然有效(If-Modified-Since或If-None-Match);
          • HIT - 響應包含直接來自緩存的有效新鮮內(nèi)容;

          默認情況下,NGINX 尊重源服務器的 Cache-Control 頭。它不會緩存響應,緩存控制設(shè)置為 Private,No-Cache 或 No-Store 或響應頭中的 Set-Cookie。NGINX 僅緩存 GET 和 HEAD 客戶端請求。

          # 調(diào)整原服務器的緩存配置
          proxy_ignore_headers Expires Set-Cookie Cache-Control;
          proxy_hide_header Cache-Control;
          proxy_hide_header Set-Cookie;

          前文中的這段配置就是為了啟用代理緩存,用以忽略源服務器的 Cache-Control 頭。

          另外,還特別添加了NGINX 服務器自己的 Cache-Control 頭的配置:

          add_header Cache-Control 'public, no-transform';

          表示允許響應被被緩存,并且在多用戶間共享。不得對資源進行轉(zhuǎn)換或轉(zhuǎn)變。

          屏幕截圖 2024-07-28 093746.png

          再看看 X-Cache 頭,也就是 $upstream_cache_status 的值已經(jīng)是 HIT 狀態(tài),表示該靜態(tài)資源已經(jīng)被代理緩存命中了。

          OK,現(xiàn)在讓我們來看看反向代理緩存都存了些什么:

          proxy-cache.png

          從截圖我們可以看到,配置的2級緩存已經(jīng)啟用了。緩存的文件是二進制的內(nèi)容,我截取一段用文本編輯器打開的數(shù)據(jù)來看看:

          proxy-cache-content.png

          這里的KEY:

          KEY: www.yao.com/js/909.86428264.js

          正是我們配置的反向代理緩存的中 proxy_cache_key 配置的數(shù)據(jù)格式:

          # 設(shè)置緩存的 key
          proxy_cache_key $host$uri$is_args$args;

          proxy_cache_purge 清除反向代理緩存

          若要手動清除緩存,可以使用 proxy_cache_purge 模塊。配置代碼如下:

          # 用于清除緩存,假設(shè)一個URL為: https://www.yao.com/#/default
          # 訪問 https://www.yao.com/#/purge/defaut 就可清除該URL的緩存
          location ~ /purge(/.*) {
              # 設(shè)置只允許指定的IP或IP段才可以清除URL緩存。
              allow 127.0.0.1;
              deny all;
              proxy_cache_purge cache_static $host$uri$is_args$args;
          }

          這個清理緩存的路徑應該只有特定(運維)人員有權(quán)限訪問,清理緩存。

          編譯安裝 Nginx 并且添加 ngx_cache_purge 模塊

          另外,proxy_cache_purge 不是 NGINX 服務器自帶的指令模塊,需要手動下載編譯安裝。

          第1步:獲取 nginx

          在 /etc/nginx/source 下執(zhí)行,具體是在那個目錄,可以自行決定:

          wget http://nginx.org/download/nginx-1.21.0.tar.gz
          tar -zxvf nginx-1.12.2.tar.gz
          第2步:獲取 ngx_cache_purge

          在 /etc/nginx/source 下執(zhí)行,具體是在那個目錄,可以自行決定,這里建議與下載的 nginx 目錄一致:

          wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz
          tar -zxvf 2.3.tar.gz
          第3步:修改 nginx 安裝配置
          ./configure --prefix=/etc/nginx  \
          --with-http_stub_status_module  \
          --with-http_ssl_module --with-stream  \
          --with-http_gzip_static_module  \
          --with-http_sub_module \
          --with-pcre  \
          --add-module=../ngx_cache_purge

          --add-module=../ngx_cache_purge 這是新增的,如果要查看以前的 configure 參數(shù),可以使用以下命令查看,然后復制后再后邊加入需要添加的配置即可。

          nginx -V
          第4步:編譯安裝

          如果以前未安裝過:

          make && make install

          編譯安裝完成后,配置 nginx。

          如果以前已經(jīng)安裝了 nginx 服務器,需要先停止 nginx 服務:

          # 默認 nginx 已經(jīng)配置為系統(tǒng)服務
          service nginx stop

          重新編譯,在 /etc/nginx/source 下執(zhí)行

          make

          將編譯好的 nginx 文件覆蓋到/etc/nginx/sbin/nginx

          cp objs/nginx /etc/nginx/sbin/nginx

          安裝編譯完成,然后按前文到需要的模塊配置 proxy_cache_purge, 然后檢測配置文件是否正確:

          nginx -t/T

          如果配置檢測通過,就可以重啟 nginx 服務:

          service nginx start

          另外,NGINX 服務器的商業(yè)版 Nginx Plus 中自帶了清理緩存的指令,有興趣的同學可以自己查閱一下相關(guān)資料,本文僅介紹 NGINX 服務器免費版的配置。

          本文到此為止我們已經(jīng)介紹了如何 NGINX 服務器配置 HTTP 緩存、與換竄相關(guān)的 HTTP 首部字段、如何在 NGIN 服務器配置反向代理緩存以及如何清理反向代理緩存。所有于開啟 HTTP 緩存相關(guān)的配置就都已經(jīng)介紹完畢了。

          開啟 HTTP 緩存后的性能對比

          最后,還是一起再看看開啟 HTTP 緩存后的性能提升對比吧:

          未開啟 HTTP 緩存

          no-cache.png
          • 完成時間:1.79秒
          • DOMContentLoaded:442毫秒
          • 加載時間:1.72秒

          開啟 HTTP 緩存

          cache.png
          • 完成時間:677毫秒
          • DOMContentLoaded:190毫秒
          • 加載時間:625秒

          效果還是很明顯的,特別是像我測試站點這種 SPA 頁面,一切都要等 js 資源加載完成了才繪制界面,加載速度至關(guān)重要!資源加載的越快,意味著用戶看到 UI 界面就越快,用戶體驗也就越好。

          小結(jié)

          本文的標題是介紹前端性能優(yōu)化,但基本都是在介紹如何配置 NGINX 服務器。所以要求前端開發(fā)工程師需要掌握必要的 NGINX 服務器相關(guān)的知識。起碼是跟前端開發(fā)或者性能優(yōu)化相關(guān)的知識點。

          然后就是對于 HTTP 協(xié)議基礎(chǔ)支持的了解,需要知道常用的 HTTP 首部字段的含有,以便于我們分析一些網(wǎng)絡問題。

          原文地址:https://juejin.cn/post/7406143794000019506
          作者: 自由的巨浪

          最后

          關(guān)注我,一起攜手進階

          歡迎關(guān)注前端早茶,與廣東靚仔攜手共同進階~

          瀏覽 65
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日日操夜夜撸 | 午夜精品久久久久蜜桃 | 五月婷婷丁香亚洲 | 琪琪色婷婷五月天 | 一级黄色欧美视频 |