2022年3月5日 星期六

vue-cli打包出gzip, brotli檔,讓網頁讀取更加快速,順便說說chunk好了

 如果你的伺服器是用nginx架設,那你可以跳過本教學

就我理解到的差異,nginx伺服器可以線上轉譯,所以在伺服器上只需提供原始檔,在讀取檔案時就可以及時把壓縮檔演算出來

想像情境為
browser 訪問 nginx
nginx 找到 file.js
file.js 透過 nginx 轉譯為file.js.gz
file.js.gz 回傳 nginx
nginx 回傳給 browser

大概會是這麼個流程(當然是很粗略的),但是線上即時轉譯吃的是伺服器的CPU,同時壓縮比越高,佔用的效能也越大,例如brotli雖然壓縮率較gzip高,但卻相當吃效能,所以大多還是採用gzip,線上轉譯固然方便,但流量大就需要考量到效能問題

因為一些原因,絕對不是因為我懶得去學nginx配置,我使用http-server架設伺服器,打個參數-g(gzip) -b(brotli)伺服器就會該靜態檔案找尋同名壓縮檔,http-server不會幫你轉譯為壓縮格式,所以gz, br檔要自行準備,官方說br會較優先使用,其次才是gz

那要如何產生呢,這就是本篇的中點(其中也包含套件分割打包chunk的配置)

// vue.config.js 設定如下

const baseConfig = {
    ...setting
}
// 正是打包才需要壓縮,不然平常開發會爆慢
if (isProd) {
const zopfli = require("@gfx/zopfli")
var zlib = require("zlib")
baseConfig.configureWebpack = {
...baseConfig.configureWebpack,
...{
      // 把套件分割打包,可以縮小每個檔案的體積,增加讀取速度
optimization: {
runtimeChunk: "single",
splitChunks: {
chunks: "all",
maxInitialRequests: Infinity,
minSize: 0,
maxSize: 4000000,
cacheGroups: {
common: {
name: "chunk-common",
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 1,
reuseExistingChunk: true,
enforce: true,
},
vendors: {
name: "chunk-vendors",
test: /[\\/]node_modules[\\/]/,
chunks: "initial",
priority: 2,
reuseExistingChunk: true,
enforce: true,
},
lodash: {
name: "chunk-lodash",
test: /[\\/]node_modules[\\/]lodash[\\/]/,
chunks: "all",
priority: 3,
reuseExistingChunk: true,
enforce: true,
},
styles: {
name: "styles",
test: /\.s?[ac]ss$/,
chunks: "all",
minChunks: 1,
reuseExistingChunk: true,
enforce: true,
},
},
},
},
},
}
baseConfig.pluginOptions = {
compression: {
brotli: {
filename: "[file].br[query]",
algorithm: "brotliCompress",
include: /\.(js|css|html|svg|json)(\?.*)?$/i,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11,
},
},
minRatio: 0.8,
},
gzip: {
filename: "[file].gz[query]",
algorithm: "gzip",
include: /\.(js|css|html|svg|json)(\?.*)?$/i,
minRatio: 0.8,
},
      // 目前壓縮率最高的演算法
zopfli: {
compressionOptions: {
numiterations: 15,
},
algorithm(input, compressionOptions, callback) {
return zopfli.gzip(input, compressionOptions, callback)
},
},
},
}
}
module.exports = baseConfig

最後就會產出
dist/service-worker.js
dist/service-worker.js.gz
dist/service-worker.js.br
......
雖然br, gz選一個就好了,我只是示範給大家看,絕對不是我懶得拿掉!!

小結:
當初研究這個是因為萬惡的IE載入速度太慢(謎之音:那些該死的公家機關還讓ie可以用到2029年),加上一個vendor.js有近20MB,光是要看到畫面得花上近半分鐘,無奈之下不得不研究一下加速,現在打包完,大多剩下幾byte到幾百K,事實上這也是很多人認為一般工程師與資深工程師的分水嶺,雖然我不這麼認同就是了,畢竟這些東西花上半天一天上網查就會了,比起經年累月累積起來的“實力”,我覺得後者更值得參考,不過學起來薪水多一點,何樂而不為呢?

沒有留言:

張貼留言