如何通過Nginx配置來優化你的網絡請求?

  • 緩存可以減少冗餘的數據傳輸。節省了網絡帶寬,從而更快的加載頁面。
  • 緩存降低了服務器的要求,從而服務器更快的響應。
  • 那麼我們使用緩存,緩存的資源文件到什麼地方去了呢?首先來看下有哪幾種緩存類型呢?

    1.memory cache: 它是將資源文件緩存到內存中。等下次請求訪問的時候不需要重新下載資源,而是直接從內存中讀取數據。

    2.disk cache: 它是將資源文件緩存到硬盤中。等下次請求的時候它是直接從硬盤中讀取。

    那麼他們兩則的區別是?

    3.memory cache(內存緩存)退出進程時數據會被清除,而disk cache(硬盤緩存)退出進程時數據不會被清除。內存讀取比硬盤中讀取的速度更快。但是我們也不能把所有數據放在內存中緩存的,因為內存也是有限的。

    memory cache(內存緩存)一般會將腳本、字體、圖片會存儲到內存緩存中。

    4.disk cache(硬盤緩存) 一般非腳本會存放在硬盤中,比如css這些。

    緩存讀取的原理:先從內存中查找對應的緩存,如果內存中能找到就讀取對應的緩存,否則的話就從硬盤中查找對應的緩存,如果有就讀取,否則的話,就重新網絡請求。

    那麼瀏覽器緩存它又分為2種: 強制緩存 和 協商緩存 。

    協商緩存原理:客戶端向服務器端發出請求,服務端會檢測是否有對應的標識,如果沒有對應的標識,服務器端會返回一個對應的標識給客戶端,客戶端下次再次請求的時候,把該標識帶過去,然後服務器端會驗證該標識,如果驗證通過了,則會響應304,告訴瀏覽器讀取緩存。如果標識沒有通過,則返回請求的資源。

    那麼協商緩存的標識又有2種:ETag/if-None-Match 和 Last-Modified/if-Modify-Since

    Last-Modified/if-Modify-Since緩存

    瀏覽器第一次發出請求一個資源的時候,服務器會返回一個last-Modify到hearer中. Last-Modify 含義是最後的修改時間。

    當瀏覽器再次請求的時候,request的請求頭會加上 if-Modify-Since,該值為緩存之前返回的 Last-Modify. 服務器收到if-Modify-Since後,根據資源的最後修改時間(last-Modify)和該值(if-Modify-Since)進行比較,如果相等的話,則命中緩存,返回304,否則, 如果 Last-Modify > if-Modify-Since, 則會給出200響應,並且更新Last-Modify為新的值。

    ETag/if-None-Match緩存

    ETag的原理和上面的last-modified是類似的。ETag則是對當前請求的資源做一個唯一的標識。該標識可以是一個字符串,文件的size,hash等。只要能夠合理標識資源的唯一性並能驗證是否修改過就可以了。ETag在服務器響應請求的時候,返回當前資源的唯一標識(它是由服務器生成的)。但是隻要資源有變化,ETag會重新生成的。瀏覽器再下一次加載的時候會向服務器發送請求,會將上一次返回的ETag值放到request header 裡的 if-None-Match裡面去,服務器端只要比較客戶端傳來的if-None-Match值是否和自己服務器上的ETag是否一致,如果一致說明資源未修改過,因此返回304,如果不一致,說明修改過,因此返回200。並且把新的Etag賦值給if-None-Match來更新該值。

    last-modified 和 ETag之間對比

    1. 在精度上,ETag要優先於 last-modified。
    2. 在性能上,Etag要遜於Last-Modified,Last-Modified需要記錄時間,而Etag需要服務器通過算法來計算出一個hash值。
    3. 在優先級上,服務器校驗優先考慮Etag。
    如何通過Nginx配置來優化你的網絡請求?

    如上我們可以看到返回值裡面有Etag的值。
    然後當我們再次刷新瀏覽器代碼的時候,瀏覽器將會帶上 if-None-Match請求頭,並賦值為上一次返回頭的Etag的值。然後和服務器端的Etag的值進行對比,如果相等的話,就會返回304 Not Modified。如下圖所示:

    如何通過Nginx配置來優化你的網絡請求?

    我們再來改下html的內容,我們再來刷新下看看,可以看到頁面內容發生改變了,因此Etag值是不一樣的。如下圖所示

    如何通過Nginx配置來優化你的網絡請求?

    然後我們繼續刷新,就會返回304了,因為它會把最新的Etag的值賦值給 if-None-Match請求頭,然後請求的時候,會把該最新值帶過去,因此如下圖所示可以看到。

    如何通過Nginx配置來優化你的網絡請求?

    強制緩存

    基本原理:瀏覽器在加載資源的時候,會先根據本地緩存資源的header中的信息(Expires 和 Cache-Control)來判斷是否需要強制緩存。如果命中的話,則會直接使用緩存中的資源。否則的話,會繼續向服務器發送請求。

    Expires 是http1.0的規範,它的值是一個絕對時間的GMT格式的時間字符串。這個時間代表的該資源的失效時間,如果在該時間之前請求的話,則都是從緩存裡面讀取的。但是使用該規範時,可能會有一個缺點就是當服務器的時間和客戶端的時間不一樣的情況下,會導致緩存失效。

    Cache-Control

    Cache-Control 是http1.1的規範,它是利用該字段max-age值進行判斷的。該值是一個相對時間,比如 Cache-Control: max-age=3600, 代表該資源的有效期是3600秒。除了該字段外,我們還有如下字段可以設置:

    no-cache: 需要進行協商緩存,發送請求到服務器確認是否使用緩存。

    no-store:禁止使用緩存,每一次都要重新請求數據。

    public:可以被所有的用戶緩存,包括終端用戶和 CDN 等中間代理服務器。

    private:只能被終端用戶的瀏覽器緩存,不允許 CDN 等中繼緩存服務器對其緩存。

    Cache-Control 與 Expires 可以在服務端配置同時啟用,同時啟用的時候 Cache-Control 優先級高。

    Nginx緩存的類型

    1.客戶端的緩存(一般指瀏覽器的緩存)。

    2.服務端的緩存(使用proxy-cache實現的)。

    Nginx如何配置

    知道Nginx虛擬機的配置文件,示例如下圖:

    server {
    server_name www.qqdeveloper.com
    location ~* \\.(html)$ {
    access_log off;
    add_header Cache-Control max-age=no-cache;
    }

    location ~* \\.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ {
    access_log off;
    add_header Cache-Control max-age=360000;
    }
    }

    ~* 的含義是:通配任意字符(且大小寫不敏感),\\轉義字符,因此 ~* .(html)$的含義是:匹配所有以.html結尾的請求

    access_log off; 的含義是 關閉日誌功能。

    add_header Cache-Control max-age=no-cache; 的含義:html文件不設置強制緩存時間,協商緩存,使用 Last-Modified。no-cache 會發起往返通信來驗證緩存的響應,但如果資源未發生變化,則不會下載,返回304。

    如下圖

    如何通過Nginx配置來優化你的網絡請求?

    add_header Cache-Control max-age=360000; 的含義給上面匹配後綴的文件設置強制緩存,且緩存的時間是360000秒,第一次訪問的時候,從服務器請求,當除了第一次以外,再次刷新瀏覽器,會從瀏覽器緩存讀取,那麼強制緩存一般是從內存裡面先讀取,如果內存沒有,再從硬盤讀取。

    如何通過Nginx配置來優化你的網絡請求?


    分享到:


    相關文章: