Nginx靜態(tài)資源優(yōu)化、壓縮、緩存詳解
優(yōu)化
Nginx對(duì)靜態(tài)資源如何進(jìn)行優(yōu)化配置。這里從三個(gè)屬性配置進(jìn)行優(yōu)化:
sendfile on; tcp_nopush on; tcp_nodeplay on;
send?le
用來開啟高效的文件傳輸模式。
| 語法 | send?le on |o?; |
|---|---|
| 默認(rèn)值 | send?le o?; |
| 位置 | http、server、location... |
請(qǐng)求靜態(tài)資源的過程:客戶端通過網(wǎng)絡(luò)接口向服務(wù)端發(fā)送請(qǐng)求,操作系統(tǒng)將這些客戶端的請(qǐng)求傳遞給服務(wù)器端應(yīng)用程序,服務(wù)器端應(yīng)用程序會(huì)處理這些請(qǐng)求,請(qǐng)求處理完成以后,操作系統(tǒng)還需要將處理得到的結(jié)果通過網(wǎng)絡(luò)適配器傳遞回去。

tcp_nopush
該指令必須在sendfile打開的狀態(tài)下才會(huì)生效,主要是用來提升網(wǎng)絡(luò)包的傳輸效率。
| 語法 | tcp_nopush on|off; |
|---|---|
| 默認(rèn)值 | tcp_nopush o?; |
| 位置 | http、server、location |
tcp_nodelay
該指令必須在keep-alive連接開啟的情況下才生效,來提高網(wǎng)絡(luò)包傳輸?shù)膶?shí)時(shí)性。
| 語法 | tcp_nodelay on|off; |
|---|---|
| 默認(rèn)值 | tcp_nodelay on; |
| 位置 | http、server、location |

經(jīng)過剛才的分析,"tcp_nopush"和”tcp_nodelay“看起來是"互斥的",那么為什么要將這兩個(gè)值都打開,這個(gè)大家需要知道的是在linux2.5.9以后的版本中兩者是可以兼容的,三個(gè)指令都開啟的好處是,sendfile可以開啟高效的文件傳輸模式,tcp_nopush開啟可以確保在發(fā)送到客戶端之前數(shù)據(jù)包已經(jīng)充分“填滿”, 這大大減少了網(wǎng)絡(luò)開銷,并加快了文件發(fā)送的速度。 然后,當(dāng)它到達(dá)最后一個(gè)可能因?yàn)闆]有“填滿”而暫停的數(shù)據(jù)包時(shí),Nginx會(huì)忽略tcp_nopush參數(shù), 然后,tcp_nodelay強(qiáng)制套接字發(fā)送數(shù)據(jù)。由此可知,TCP_NOPUSH可以與TCP_NODELAY一起設(shè)置,它比單獨(dú)配置TCP_NODELAY具有更強(qiáng)的性能。所以我們可以使用如下配置來優(yōu)化Nginx靜態(tài)資源的處理。
壓縮
經(jīng)過上述內(nèi)容的優(yōu)化,我們?cè)俅嗡伎家粋€(gè)問題,假如在滿足上述優(yōu)化的前提下,我們傳送一個(gè)1M的數(shù)據(jù)和一個(gè)10M的數(shù)據(jù)那個(gè)效率高?,答案顯而易見,傳輸內(nèi)容小,速度就會(huì)快。那么問題又來了,同樣的內(nèi)容,如果把大小降下來,我們腦袋里面要蹦出一個(gè)詞就是"壓縮",接下來,我們來學(xué)習(xí)Nginx的靜態(tài)資源壓縮模塊。
在Nginx的配置文件中可以通過配置gzip來對(duì)靜態(tài)資源進(jìn)行壓縮。
體驗(yàn)示例
我們?cè)趆tml目錄下放入一個(gè)jquery-1.10.1.js文件,訪問 http://127.0.0.1/jquery-1.10.1.js,結(jié)果如下:

配置開啟壓縮后,如下:
gzip on; gzip_types application/javascript;

相關(guān)配置
gzip
該指令用于開啟或者關(guān)閉gzip功能。
| 語法 | gzip on|off; |
|---|---|
| 默認(rèn)值 | gzip off; |
| 位置 | http、server、location... |
注意只有該指令為打開狀態(tài),下面的指令才有效果。
gzip_types
該指令可以根據(jù)響應(yīng)頁的MIME類型選擇性地開啟Gzip壓縮功能。
| 語法 | gzip_types mime-type ...; |
|---|---|
| 默認(rèn)值 | gzip_types text/html; |
| 位置 | http、server、location |
所選擇的值可以從mime.types文件中進(jìn)行查找,有些類型比如圖片、視頻等本身壓縮了也節(jié)省不了多少空間,反而會(huì)浪費(fèi)CPU資源,所以在選擇壓縮的時(shí)候需要注意是否有必要進(jìn)行壓縮。
http{
gzip_types application/javascript;
}gzip_comp_level
該指令用于設(shè)置Gzip壓縮程度,級(jí)別從1-9,1表示壓縮程度最低,效率最高,9剛好相反,壓縮程度最高,但是效率最低最費(fèi)時(shí)間,所以使用時(shí),注意并不是級(jí)別越高越好。建議設(shè)置在中間值5/6即可。
| 語法 | gzip_comp_level level; |
|---|---|
| 默認(rèn)值 | gzip_comp_level 1; |
| 位置 | http、server、location |
gzip_vary
該指令用于設(shè)置使用Gzip進(jìn)行壓縮發(fā)送是否攜帶“Vary:Accept-Encoding”頭域的響應(yīng)頭部。主要是告訴接收方,所發(fā)送的數(shù)據(jù)經(jīng)過了Gzip壓縮處理。
| 語法 | gzip_vary on|off; |
|---|---|
| 默認(rèn)值 | gzip_vary off; |
| 位置 | http、server、location |
開啟后,在瀏覽器中可以看到多了一項(xiàng),如下標(biāo)紅部分:

gzip_buffers
該指令用于處理請(qǐng)求壓縮的緩沖區(qū)數(shù)量和大小。
| 語法 | gzip_buffers number size; |
|---|---|
| 默認(rèn)值 | gzip_buffers 32 4k|16 8k; |
| 位置 | http、server、location |
其中number:指定Nginx服務(wù)器向系統(tǒng)申請(qǐng)緩存空間個(gè)數(shù),size指的是每個(gè)緩存空間的大小。主要實(shí)現(xiàn)的是申請(qǐng)number個(gè)每個(gè)大小為size的內(nèi)存空間。這個(gè)值的設(shè)定一般會(huì)和服務(wù)器的操作系統(tǒng)有關(guān),所以建議此項(xiàng)不設(shè)置,使用默認(rèn)值即可。
gzip_disable
針對(duì)不同種類客戶端發(fā)起的請(qǐng)求,可以選擇性地開啟和關(guān)閉Gzip功能。
| 語法 | gzip_disable regex ...; |
|---|---|
| 默認(rèn)值 | — |
| 位置 | http、server、location |
regex:根據(jù)客戶端的瀏覽器標(biāo)志(user-agent)來設(shè)置,支持使用正則表達(dá)式。指定的瀏覽器標(biāo)志不使用Gzip.該指令一般是用來排除一些明顯不支持Gzip的瀏覽器。
gzip_disable "MSIE [1-6]\.";
gzip_http_version
針對(duì)不同的HTTP協(xié)議版本,可以選擇性地開啟和關(guān)閉Gzip功能。
| 語法 | gzip_http_version 1.0|1.1; |
|---|---|
| 默認(rèn)值 | gzip_http_version 1.1; |
| 位置 | http、server、location |
該指令是指定使用Gzip的HTTP最低版本,該指令一般采用默認(rèn)值即可。
gzip_min_length
進(jìn)行壓縮響應(yīng)頁面的最小長度,響應(yīng)頁面的大小可以通過頭信息中的Content-Length來獲取,如果設(shè)置的值大于content-length將不進(jìn)行壓縮。
| 語法 | gzip_min_length length; |
|---|---|
| 默認(rèn)值 | gzip_min_length 20; |
| 位置 | http、server、location |
nignx計(jì)量大小的單位:bytes[字節(jié)] / kb[千字節(jié)] / M[兆]
例如: 1024 / 10k|K / 10m|M
Web緩存
Web緩存是指一個(gè)Web資源(如html頁面,圖片,js,數(shù)據(jù)等)存在于Web服務(wù)器和客戶端(瀏覽器)之間的副本。緩存會(huì)根據(jù)進(jìn)來的請(qǐng)求保存輸出內(nèi)容的副本;當(dāng)下一個(gè)請(qǐng)求來到的時(shí)候,如果是相同的URL,緩存會(huì)根據(jù)緩存機(jī)制決定是直接使用副本響應(yīng)訪問請(qǐng)求,還是向源服務(wù)器再次發(fā)送請(qǐng)求。比較常見的就是瀏覽器會(huì)緩存訪問過網(wǎng)站的網(wǎng)頁,當(dāng)再次訪問這個(gè)URL地址的時(shí)候,如果網(wǎng)頁沒有更新,就不會(huì)再次下載網(wǎng)頁,而是直接使用本地緩存的網(wǎng)頁。只有當(dāng)網(wǎng)站明確標(biāo)識(shí)資源已經(jīng)更新,瀏覽器才會(huì)再次下載網(wǎng)頁。
Web緩存種類
- 客戶端緩存: 瀏覽器緩存。
- 服務(wù)端緩存: Nginx / Redis / Memcached等。
瀏覽器緩存
是為了節(jié)約網(wǎng)絡(luò)的資源加速瀏覽,瀏覽器在用戶磁盤上對(duì)最近請(qǐng)求過的文檔進(jìn)行存儲(chǔ),當(dāng)訪問者再次請(qǐng)求這個(gè)頁面時(shí),瀏覽器就可以從本地磁盤顯示文檔,這樣就可以加速頁面的閱覽。
為什么使用瀏覽器緩存
- 成本最低的一種緩存實(shí)現(xiàn)。
- 減少網(wǎng)絡(luò)帶寬消耗。
- 降低服務(wù)器壓力。
- 減少網(wǎng)絡(luò)延遲,加快頁面打開速度 。
瀏覽器緩存的執(zhí)行流程
HTTP協(xié)議中和頁面緩存相關(guān)的字段,我們先來認(rèn)識(shí)下:
| header | 說明 |
|---|---|
| Expires | 緩存過期的日期和時(shí)間 |
| Cache-Control | 設(shè)置和緩存相關(guān)的配置信息 |
| Last-Modified | 請(qǐng)求資源最后修改時(shí)間 |
| ETag | 請(qǐng)求變量的實(shí)體標(biāo)簽的當(dāng)前值,比如文件的MD5值 |

(1)用戶首次通過瀏覽器發(fā)送請(qǐng)求到服務(wù)端獲取數(shù)據(jù),客戶端是沒有對(duì)應(yīng)的緩存,所以需要發(fā)送request請(qǐng)求來獲取數(shù)據(jù);
(2)服務(wù)端接收到請(qǐng)求后,獲取服務(wù)端的數(shù)據(jù)及服務(wù)端緩存的允許后,返回200的成功狀態(tài)碼并且在響應(yīng)頭上附上對(duì)應(yīng)資源以及緩存信息;
(3)當(dāng)用戶再次訪問相同資源的時(shí)候,客戶端會(huì)在瀏覽器的緩存目錄中查找是否存在響應(yīng)的緩存文件
(4)如果緩存中有,直接響應(yīng),如果沒有找到對(duì)應(yīng)的緩存文件,從服務(wù)器重新獲取。
(5)如果有緩存文件,接下來對(duì)緩存文件是否過期進(jìn)行判斷,過期的判斷標(biāo)準(zhǔn)是(Expires),
(6)如果沒有過期,則直接從本地緩存中返回?cái)?shù)據(jù)進(jìn)行展示
(7)如果Expires過期,接下來需要判斷緩存文件是否發(fā)生過變化
(8)判斷的標(biāo)準(zhǔn)有兩個(gè),一個(gè)是ETag(Entity Tag),一個(gè)是Last-Modified
(9)判斷結(jié)果是未發(fā)生變化,則服務(wù)端返回304,直接從緩存文件中獲取數(shù)據(jù)
(10)如果判斷是發(fā)生了變化,重新從服務(wù)端獲取數(shù)據(jù),并根據(jù)緩存協(xié)商(服務(wù)端所設(shè)置的是否需要進(jìn)行緩存數(shù)據(jù)的設(shè)置)來進(jìn)行數(shù)據(jù)緩存。
瀏覽器緩存相關(guān)指令
Nginx需要進(jìn)行緩存相關(guān)設(shè)置,就需要用到如下的指令。
expires
expires:該指令用來控制頁面緩存的作用。可以通過該指令控制HTTP應(yīng)答中的“Expires"和”Cache-Control"
| 語法 | expires [modified] time expires epoch|max|off; |
|---|---|
| 默認(rèn)值 | expires off; |
| 位置 | http、server、location |
- time:可以整數(shù)也可以是負(fù)數(shù),指定過期時(shí)間,如果是負(fù)數(shù),Cache-Control則為no-cache,如果為整數(shù)或0,則Cache-Control的值為max-age=time;
- epoch: 指定Expires的值為'1 January,1970,00:00:01 GMT'(1970-01-01 00:00:00),Cache-Control的值no-cache
- max:指定Expires的值為'31 December2037 23:59:59GMT' (2037-12-31 23:59:59) ,Cache-Control的值為10年
- off:默認(rèn)不緩存。
add_header
add_header指令是用來添加指定的響應(yīng)頭和響應(yīng)值。
| 語法 | add_header name value [always]; |
|---|---|
| 默認(rèn)值 | — |
| 位置 | http、server、location... |
Cache-Control作為響應(yīng)頭信息,可以設(shè)置如下值:
| 指令 | 說明 |
|---|---|
| must-revalidate | 可緩存但必須再向源服務(wù)器進(jìn)行確認(rèn) |
| no-cache | 緩存前必須確認(rèn)其有效性 |
| no-store | 不緩存請(qǐng)求或響應(yīng)的任何內(nèi)容 |
| no-transform | 代理不可更改媒體類型 |
| public | 可向任意方提供響應(yīng)的緩存 |
| private | 僅向特定用戶返回響應(yīng) |
| proxy-revalidate | 要求中間緩存服務(wù)器對(duì)緩存的響應(yīng)有效性再進(jìn)行確認(rèn) |
| max-age=<秒> | 響應(yīng)最大Age值 |
| s-maxage=<秒> | 公共緩存服務(wù)器響應(yīng)的最大Age值 |
測(cè)試
location ~ .*\.(html|js|css|png)$ {
expires 1000;
}
如上,我們?cè)O(shè)置瀏覽器對(duì)html、js、css、png類型的響應(yīng)進(jìn)行緩存,緩存時(shí)間為1000秒, 然后再次訪問 http://118.190.152.59/jquery-1.10.1.js 返回的響應(yīng)信息中就可以看到多了幾項(xiàng),如下:

補(bǔ)充一下,從請(qǐng)求上看下緩存的效果,第一次訪問的時(shí)候狀態(tài)碼200,傳輸文件267K,當(dāng)我們刷新頁面后會(huì)發(fā)現(xiàn) 狀態(tài)碼為304并且傳輸欄里也變?yōu)榱艘丫彺妗?/p>


我們?cè)僭囅?add_header相關(guān)的指令,如下:
location ~ .*\.(html|js|css|png)$ {
expires 1000;
add_header Cache-Control no-store;
}
如上,我們指定瀏覽器不緩存請(qǐng)求或響應(yīng)的任何內(nèi)容,清空瀏覽器緩存后,多次訪問資源每次都會(huì)請(qǐng)求服務(wù)器,狀態(tài)碼200,傳輸都會(huì)顯示資源的大小。


總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用Nginx+Tomcat實(shí)現(xiàn)負(fù)載均衡的全過程
很多用到nginx的地方都是作為靜態(tài)伺服器,這樣可以方便緩存那些靜態(tài)文件,比如CSS,JS,html,htm等文件,下面這篇文章主要給大家介紹了關(guān)于使用Nginx+Tomcat實(shí)現(xiàn)負(fù)載均衡的相關(guān)資料,需要的朋友可以參考下2022-05-05
nginx實(shí)現(xiàn)一個(gè)域名配置多個(gè)laravel項(xiàng)目的方法示例
這篇文章主要介紹了nginx實(shí)現(xiàn)一個(gè)域名配置多個(gè)laravel項(xiàng)目的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01
Nginx HTTP反向代理負(fù)載均衡實(shí)驗(yàn)教程
文章描述了在192.168.65.135上部署Nginx作為七層HTTP反向代理,將www.xiaotiantian.org的流量輪詢轉(zhuǎn)發(fā)到兩臺(tái)后端Web服務(wù)器,并驗(yàn)證了反向代理的負(fù)載均衡和故障轉(zhuǎn)移功能2025-12-12
使用Nginx實(shí)現(xiàn)根據(jù) IP 匹配指定 URL
最近的一個(gè)項(xiàng)目,需要特定的IP訪問某專題頁面的時(shí)候跳轉(zhuǎn)到網(wǎng)站首頁,思考了下,直接使用NGINX實(shí)現(xiàn),分享給大家。2014-09-09
nginx配置訪問圖片路徑以及html靜態(tài)頁面的調(diào)取方法
這篇文章主要介紹了詳解nginx配置訪問圖片路徑以及html靜態(tài)頁面的調(diào)取方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。2016-12-12

