一、文件壓縮的好處
前端生產環境中將js、css、圖片等文件進行壓縮的好處顯而易見,通過減少數據傳輸量減小傳輸時間,節省服務器網絡帶寬,提高前端性能。
二、http協議如何支持壓縮文件的傳輸
1、瀏覽器請求數據時,通過Accept-Encoding說明自己可以接受的壓縮方法
2、服務端接收到請求后,選取Accept-Encoding中的一種對響應數據進行壓縮
3、服務端返回響應數據時,在Content-Encoding字段中說明數據的壓縮方式
4、瀏覽器接收到響應數據后根據Content-Encoding對結果進行解壓
注:如果服務器沒有對響應數據進行壓縮,則不返回Content-Encoding,瀏覽器也不進行解壓
三、什么時候壓縮

四、服務器響應請求時壓縮(nginx)
nginx中有關gzip的配置項如下:
1、gzip on|off:默認off
開啟或者關閉gzip模塊
2、gzip_comp_level 4:默認1,建議選擇為4
gzip壓縮比/壓縮級別,壓縮級別 1-9,級別越高壓縮率越大,壓縮時間越長,消耗CPU也越大。
3、gzip_min_length 1k:默認0,不管頁面多大都壓縮
設置允許壓縮的頁面最小字節數,頁面字節數從header頭中的Content-Length中進行獲取。
建議設置成大於1k的字節數,小於1k可能會越壓越大。 即: gzip_min_length 1024
4、gzip_static on|off:默認off
gzip_static是nginx對於靜態文件的處理模塊,可以讀取預先壓縮的gz文件,多與構建時壓縮同時使用,詳見下節構建時壓縮介紹
5、更多配置信息參考:Nginx的gzip
五、構建時壓縮(webpack)
webpack的compression-webpack-plugin插件用於支持構建項目時壓縮文件,Vue項目為例,具體配置如下:
1、首先安裝插件,命令:npm install --save-dev compression-webpack-plugin
2、在config/index.js文件中打開Gzip開關,配置需要壓縮的文件擴展名

3、webpack.prod.conf.js中設置具體壓縮配置項

4、打包后會同時保留原文件和壓縮后的文件,存儲等條件允許的情況下,原文件也建議發布到服務器以支持不兼容gzip的瀏覽器
5、服務端nginx啟動gzip_static
gzip_static是nginx對於靜態文件的處理模塊,該模塊可以讀取預先壓縮的gz文件,這樣可以減少每次請求進行gzip壓縮的CPU資源消耗。該模塊啟用后,nginx首先檢查是否存在請求靜態文件的gz結尾的文件,如果有則直接返回該gz文件內容。
為了要兼容不支持gzip的瀏覽器,啟用gzip_static模塊就必須同時保留原始靜態文件和gz文件。這樣的話,在有大量靜態文件的情況下,將會大大增加磁盤空間。我們可以利用nginx的反向代理功能實現只保留gz文件(參考文章中提到本文未嘗試)。
nginx需要安裝http_gzip_static_module以支持gzip_static,具體方法見《源碼安裝nginx》
六、生產環境:proxy_pass+gzip
上線后發現生產環境中靜態文件的壓縮配置沒有起作用,經過定位發現生產環境加了反向代理導致nginx沒有返回.gz文件。看到參考文章中二、三兩篇時確定是gzip_http_version和proxy_set_header Accept-Encoding配置問題。

如果我們使用了proxy_pass進行反向代理,那么nginx和upstream server之間默認是用HTTP/1.0協議通信的。
如果我們的Cache Server也是nginx,而前端的nginx沒有開啟gzip。 同時,我們后端的nginx上沒有設置gzip_http_version為1.0,那么Cache的url將不會進行gzip壓縮。
所以,最終的解決方案是,在靜態文件服務nginx中配置gzip_http_version為1.0
同時,反向代理服務器應該添加請求頭proxy_set_header Accept-Encoding ‘gzip’,通知靜態文件服務器客戶端能夠理解的gzip壓縮文件,使其返回.gz文件
參考
Nginx開啟Gzip詳解(gzip_http_version部分):https://blog.csdn.net/zhuyiquan/article/details/52709864
nginx反向代理和gzip_static模塊使用:https://yq.aliyun.com/ziliao/46446
