本程式碼研究室是壓縮及壓縮網路酬載程式碼研究室的延伸內容,且假設您已熟悉壓縮的基本概念。相較於 gzip
等其他壓縮演算法,本程式碼研究室將探討 Brotli 壓縮如何進一步降低壓縮率和應用程式整體大小。
測量
著手新增最佳化項目之前,最好先分析應用程式的目前狀態。
- 按一下「Remix to Edit」即可編輯專案。
- 如要預覽網站,請按下「View App」,然後按下「Fullscreen」。
在先前的壓縮及壓縮網路酬載程式碼研究室中,我們將 main.js
的大小從 225 KB 縮減為 61.6 KB。在本程式碼研究室中,您將探索 Brotli 壓縮如何進一步縮減這個套件大小。
Brotli 壓縮
Brotli 是較新的壓縮演算法,文字壓縮結果比 gzip
更好。根據 CertSimple,Britli 的效能具有:
- JavaScript 比
gzip
小 14% - HTML 比
gzip
小 21% - CSS 比
gzip
小 17%
如要使用 Brotli,你的伺服器必須支援 HTTPS。大部分瀏覽器最新版本支援 Brotli。支援 Brotli 的瀏覽器會在 Accept-Encoding
標頭中加入 br
:
Accept-Encoding: gzip, deflate, br
您可以透過 Chrome 開發人員工具網路分頁 (Command+Option+I
或 Ctrl+Alt+I
) 中的 Content-Encoding
欄位,判斷使用哪種壓縮演算法:
啟用 Brotli
動態壓縮
動態壓縮牽涉到即時壓縮瀏覽器要求的資產。
優點
- 您不需要建立與更新已儲存的資產壓縮版本。
- 對於動態產生的網頁而言,即時壓縮效果尤佳。
缺點
- 壓縮較高層級的檔案可以提高壓縮率,但所需時間會拉長。這可能會導致效能命中,因為使用者等待素材資源在伺服器送出之前先壓縮。
使用 Node/Express 動態壓縮
server.js
檔案負責設定託管應用程式的節點伺服器。
var express = require('express');
var app = express();
app.use(express.static('public'));
var listener = app.listen(process.env.PORT, function() {
console.log('Your app is listening on port ' + listener.address().port);
});
目前只會匯入 express
,並使用 express.static
中介軟體在 public/directory
中載入所有靜態 HTML、JS 和 CSS 檔案 (而且這些檔案是由 webpack 與每個版本建立)。
為確保所有資產每次要求時都會使用 brotli 壓縮,可以使用 shrink-ray
模組。第一步,是將其新增為 package.json
中的 devDependency
:
"devDependencies": {
//...
"shrink-ray": "^0.1.3"
},
並匯入伺服器檔案 server.js
:
var express = require('express');
var shrinkRay = require('shrink-ray');
並在掛接 express.static
前將其新增為中介軟體:
//...
var app = express();
// compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
現在,請重新載入應用程式,然後在「網路」面板中查看軟體包大小:
您現在可以在 Content-Encoding
標頭中看到 brotli
從 bz
套用。main.bundle.js
從 225 KB 縮減為 53.1 KB!相較於 gzip
(61.6 KB),這個數量縮減約 14%。
靜態壓縮
靜態壓縮的原理是將資產壓縮並儲存。
優點
- 再也不用擔心因為壓縮等級造成延遲的問題。因為現在可以直接擷取檔案,不需要進行任何即時壓縮。
缺點
- 每個版本都需要壓縮資產。如果使用高壓縮率,建構時間可能會大幅增加。
使用 Node/Express 和 webpack 進行靜態壓縮
由於靜態壓縮需要預先壓縮檔案,因此您可以在建構步驟中修改 webpack 設定來壓縮資產。這時可以使用 brotli-webpack-plugin
。
第一步,是將其新增為 package.json
中的 devDependency
:
"devDependencies": {
//...
"brotli-webpack-plugin": "^1.1.0"
},
如同任何其他 webpack 外掛程式,請將其匯入設定檔 webpack.config.js
:
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
並在 Plugins 陣列中加入這個程式碼:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
外掛程式陣列使用下列引數:
asset
:目標資產名稱。- 系統會將
[file]
替換為原始素材資源檔案名稱。 test
:系統會處理所有與這個規則運算式相符的資產 (也就是結尾為.js
的 JavaScript 資產)。
舉例來說,main.js
可能會重新命名為 main.js.br
。
當應用程式重新載入並重新建構時,現在系統會建立主要套件的壓縮版本。開啟 Glitch 主控台,以查看節點伺服器提供的最終 public/
目錄中的內容。
- 按一下「工具」按鈕。
- 按一下「Console」按鈕。
- 在主控台中執行下列指令,變更為
public
目錄,以查看當中的所有檔案:
cd public
ls -lh
軟體包 main.bundle.js.br
的壓縮版本現在也儲存在此處,與 main.bundle.js
相比大小減少約 76% (225 KB,比 53 KB)。
接下來,指示伺服器在要求原始 JS 版本時傳送這些經過暴力壓縮的檔案。方法是在檔案透過 express.static
提供前,在 server.js
中定義新路徑。
var express = require('express');
var app = express();
app.get('*.js', (req, res, next) => {
req.url = req.url + '.br';
res.set('Content-Encoding', 'br');
res.set('Content-Type', 'application/javascript; charset=UTF-8');
next();
});
app.use(express.static('public'));
app.get
用於指示伺服器如何回應特定端點的 GET
要求。接著,回呼函式會用於定義處理這項要求的方式。路線的運作方式如下:
- 將
'*.js'
指定為第一個引數,表示每個觸發端點都會執行此方法,以擷取 JS 檔案。 - 在回呼中,
.br
會附加至要求的網址,Content-Encoding
回應標頭則設為br
。 Content-Type
標頭會設為application/javascript; charset=UTF-8
以指定 MIME 類型。- 最後,
next()
可確保該序列繼續進行任何可能的回呼。
由於部分瀏覽器可能不支援代理壓縮,因此請先檢查 Accept-Encoding
要求標頭包含 br
,確認系統支援 brotli 壓縮後,再傳回亂數壓縮檔案:
var express = require('express');
var app = express();
app.get('*.js', (req, res, next) => {
if (req.header('Accept-Encoding').includes('br')) {
req.url = req.url + '.br';
console.log(req.header('Accept-Encoding'));
res.set('Content-Encoding', 'br');
res.set('Content-Type', 'application/javascript; charset=UTF-8');
}
next();
});
app.use(express.static('public'));
應用程式重新載入後,請再次查看「網路」面板。
大功告成!您已使用 Brotli 壓縮功能進一步壓縮素材資源!
結論
本程式碼研究室說明 brotli
如何進一步縮減應用程式的整體大小。如果支援,brotli
是比 gzip
更強大的壓縮演算法。