項目打包結束后,在終端上會展示三列(File、Size、Gzipped),Gzipped壓縮后的文件大小顯然比Size小,而我們打包后的文件都是沒有壓縮的,如果項目文件很大就會影響到首頁白屏時間過長,因此研究了下
Gzip。
一、Gzip壓縮原理
1.1 原理
Gzip 壓縮背后的原理,是在一個文本文件中找出一些重復出現的字符串、臨時替換它們,從而使整個文件變小。根據這個原理,文件中代碼的重復率越高,那么壓縮的效率就越高,使用 Gzip的收益也就越大。反之亦然。
1.1.1 HTTP壓縮原理
HTTP 壓縮是一種內置到網頁服務器和網頁客戶端中以改進傳輸速度和帶寬利用率的方式。在使用 HTTP 壓縮的情況下,HTTP 數據在從服務器發(fā)送前就已壓縮:兼容的瀏覽器將在下載所需的格式前宣告支持何種方法給服務器;不支持壓縮方法的瀏覽器將下載未經壓縮的數據。最常見的壓縮方案包括 Gzip 和 Deflate。
1.1.2 webpack 的 Gzip 和服務端的Gzip
參考 webpack優(yōu)化性能/首屏加載時間
一般來說,Gzip 壓縮是服務器的活兒:服務器了解到我們這邊有一個 Gzip 壓縮的需求,它會啟動自己的 CPU 去為我們完成這個任務。而壓縮文件這個過程本身是需要耗費時間的,大家可以理解為我們以服務器壓縮的時間開銷和 CPU 開銷(以及瀏覽器解析壓縮文件的開銷)為代價,省下了一些傳輸過程中的時間開銷。
既然存在著這樣的交換,那么就要求我們學會權衡。服務器的 CPU 性能不是無限的,如果存在大量的壓縮需求,服務器也扛不住的。服務器一旦因此慢下來了,用戶還是要等。Webpack 中 Gzip 壓縮操作的存在,事實上就是為了在構建過程中去做一部分服務器的工作,為服務器分壓。
因此,這兩個地方的 Gzip 壓縮,誰也不能替代誰。它們必須和平共處,好好合作。作為開發(fā)者,我們也應該結合業(yè)務壓力的實際強度情況,去做好這其中的權衡。
1.2 實現
不是每個瀏覽器都支持Gzip的,如何知道客戶端是否支持Gzip呢,請求頭中有個Accept-Encoding:gzip來標識對壓縮的支持??蛻舳薶ttp請求頭聲明瀏覽器支持的壓縮方式,服務端配置啟用壓縮,壓縮的文件類型,壓縮方式。當客戶端請求到服務端的時候,服務器解析請求頭,如果客戶端支持Gzip壓縮,響應時對請求的資源進行壓縮并返回給客戶端,瀏覽器按照自己的方式解析,在http響應頭,我們可以看到content-encoding:gzip,這是指服務端使用了Gzip的壓縮方式(圖1-1)。

1.3 如何看是否使用了Gzip壓縮的文件
開發(fā)者工具 -> network -> content-encoding:gzip


1.3 Gzip優(yōu)缺點
優(yōu)點
減少文件大小。Gzip壓縮比率在3到10倍左右,可以大大節(jié)省服務器的網絡帶寬。而在實際應用中,并不是對所有文件進行壓縮,通常只是壓縮靜態(tài)文件。 減少文件大小有兩個明顯的好處,①是可以減少存儲空間,②是通過網絡傳輸文件時,可以減少傳輸的時間。 對于帶寬較低的服務器是一種利好,開啟后可以加快我們網站的打開速度,原理是經過服務器壓縮,客戶端瀏覽器快速解壓的原理,可以大大減少網站流量。
缺點
- 需要nginx、服務端的支持,占用了一些服務器和客戶端的CPU;
- 操作失誤,會造成網站無法訪問;
- 蜘蛛無法進行爬行,造成收錄不佳;
- 谷歌可以完美的支持Gzip壓縮,百度支持的并不太好;
二、啟用Gzip
2.1 vue.config.js
安裝npm i compression-webpack-plugin@5.0.1
如果安裝的時候報RROR TypeError:Cannot read property ‘tapPromise‘ of undefined可能是compression-webpack-plugin版本問題(采用5.0.1版本)
// webpack啟用Gzip壓縮
const CompressionPlugin = require('compression-webpack-plugin');
const productionGzipExtensions = ['js', 'css'];
const isPRD = process.env.NODE_ENV === 'production';
module.exports = {
configureWebpack: {
plugins: isPRD ? [
// 使用Gzip壓縮文件 - https://segmentfault.com/a/1190000012571492
// 報錯:"TypeError: Cannot read property 'tapPromise' of undefined"是compression-webpack-plugin版本問題5.0.1
new CompressionPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 10240,
minRatio: 0.8
})
] : []
},
}
2.2 服務端
這里使用的是node,所以以node配置為例
安裝compression npm i compression
// 服務端開啟Gzip支持
var compression = require('compression');
//盡量在其他中間件前使用compression
app.use(compression());
2.3 nginx配置
http {
# nginx開啟Gzip:若沒有找到.gz,會動態(tài)壓縮,因此建議前端打包成.gz文件
# 是否啟用Gzip(on為啟用,off為關閉)
gzip on;
# 設置允許壓縮的頁面最小字節(jié)數,頁面字節(jié)數從header頭中的Content-Length中進行獲取。默認值是0,不管頁面多大都壓縮。建議設置成大于1k的字節(jié)數,小于1k可能會越壓越大。
gzip_min_length 1k;
# 獲取多少內存用于緩存壓縮結果,‘4 16k’表示以16k*4為單位獲得
gzip_buffers 4 16k;
# Gzip壓縮比(1~9),越小壓縮效果越差,但是越大處理越慢,所以一般取中間值;
gzip_comp_level 5;
# 對特定的MIME類型生效,其中'text/html'被系統(tǒng)強制啟用(少啥類型就添加啥)
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 識別http協議的版本,早起瀏覽器可能不支持Gzip自解壓,用戶會看到亂碼
gzip_http_version 1.1;
# 啟用應答頭"Vary: Accept-Encoding"
gzip_vary on;
# ie6以下禁用Gzip
gzip_disable "MSIE [1-6]\.";
}
三、注意點
- 低版本瀏覽器兼容問題,如果你的站點必須在window95的網景1.0瀏覽器上,你可能不想要壓縮文件。Apache mod_deflate設置了一些忽略規(guī)則來專門為舊瀏覽器。
- 建議只壓縮HTML,CSS,JAVARSCRIPT;大多數的圖片,音樂和視頻都已經壓縮過了,不要浪費時間來壓縮他們了。
- CPU負載:在傳輸過程中壓縮文件耗費CPU但是節(jié)省帶寬(用空間換時間)。
參考文章
相關文章
二、webpack優(yōu)化之去除冗余代碼(vue)
三、webpack優(yōu)化之第三方庫使用 CDN 加載(vue)