記一次管理平臺webpack優(yōu)化

最近對公司商務(wù)運(yùn)營管理平臺做了部分優(yōu)化,優(yōu)化后包體積減小為原來的43%,性能有很大提升。

優(yōu)化前

原配置文件中已包含部分優(yōu)化,包括

  • 使用compression-webpack-plugin開啟gzip壓縮
  • 使用svg-sprite-loader將svg文件打包成雪碧圖
  • 使用optimization.splitChunks做代碼分割

......
在此基礎(chǔ)上仍有很大優(yōu)化空間,首先借助 webpack-bundle-analyzer 將打包后的內(nèi)容展示為方便交互的樹狀圖,我們可以很直觀的看到有哪些比較大的模塊,然后做針對性優(yōu)化。

image.png

可以看到總體為7.71M,其中node_modules占用較多,所以可進(jìn)行較明顯的構(gòu)建優(yōu)化.

CDN+external

> CDN 的工作原理是將源站的資源緩存到位于全球各地的 CDN 節(jié)點(diǎn)上,用戶請求資源時(shí),就近返回節(jié)點(diǎn)上緩存的資源,而不需要每個(gè)用戶的請求都回您的源站獲取,避免網(wǎng)絡(luò)擁塞、緩解源站壓力,保證用戶訪問資源的速度和體驗(yàn)。

可以看到打包模塊中將一些引入庫也打包進(jìn)來,這里我們可以采用引入外鏈cdn取消對較大依賴模塊的打包。
在vue.config.js中添加如圖配置


image.png

同時(shí)在public中的index.html中引入cdn鏈接


image.png

需要注意點(diǎn),在 html 中配置的 CDN 引入腳本最好要在 body 內(nèi)的最底部,因?yàn)椋?/p>

  • 如果放在 body 上面或 header 內(nèi),則加載會(huì)阻塞整個(gè)頁面渲染。
  • 如果放在 body 外,則會(huì)在業(yè)務(wù)代碼被加載之后加載,模塊中使用了該模塊將會(huì)報(bào)錯(cuò)
  • CDN最好采用公司內(nèi)部CDN,這里使用了vue及element官網(wǎng)鏈接和服務(wù)較好的bootcdn

按需引入

很多element組件只用到了較少一部分,所以可采用按需引入
安裝插件babel-plugin-component后修改.babelrc文件

{
    "presets": [],
    "plugins": [
        [
          "component",
          {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
          }
        ]
      ]
}

在需要的地方引入,例

import { Loading } from "element-ui";

語言包優(yōu)化

某些場景下,語言包會(huì)占用整個(gè)包體積的非常大一部分。實(shí)際上庫本身的邏輯不會(huì)很大,moment 就是一個(gè)很好例子。如果是新項(xiàng)目,推薦使用dayjs替代moment,它只有2k,此處用了不影響原邏輯我們?nèi)匝佑胢oment,把不使用的語言包過濾掉,推薦使用 ContextReplacementPlugin,他可以過濾掉不使用的語言,也可以用webpack的IgnorePlugin插件

image.png

const ContextReplacementPlugin = require("webpack/lib/ContextReplacementPlugin");
config.plugin("ignore").use(new ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/));
image.png

過濾后僅為原來25%

去除console

日常開發(fā)為了方便調(diào)試,代碼中會(huì)有一些console,但是在生產(chǎn)環(huán)境中為了信息安全這些console是不能出現(xiàn)的,這里我們使用terser-webpack-plugin插件來去掉console。該插件通常用語代碼壓縮,有類似功能的插件還有uglifyjs-webpack-plugin,但uglifyjs-webpack-plugin缺點(diǎn)是不支持es6
安裝

npm install terser-webpack-plugin --save-dev

使用

const TerserPlugin = require("terser-webpack-plugin");

vue.config.js的configureWebpack中添加

 optimization: {
            minimizer: [
                new TerserPlugin({
                    terserOptions: {
                        compress: {
                            pure_funcs: ["console.log"]
                        }
                    }
                })
            ]
        },

打包時(shí)發(fā)現(xiàn)報(bào)錯(cuò)


image.png

排查后發(fā)現(xiàn)原因是webpack和terser插件的版本差異,terser目前最新版為5.0.2,但我們項(xiàng)目中使用的事webpack4.x,所以要安裝terser插件的4.x版本,安裝后重新build正常。
在打包后的dist文件夾app.js中搜索console.log未發(fā)現(xiàn)說明生效。


image.png

壓縮圖片

項(xiàng)目中有較多小于2k的icon和小圖片可使用file-loaderurl-loader處理

image.png

原理是url-loader可將小于limit的圖片轉(zhuǎn)成base64格式,大于limit的圖片由file-loader編譯
配置如下

const imagesRule = config.module.rule("images");
        imagesRule.uses.clear();
        imagesRule
            .use("file-loader")
            .loader("url-loader")
            .options({
                limit: 16384, // 小于2k轉(zhuǎn)長base64
                fallback: {
                    loader: "file-loader",
                    options: {
                        outputPath: "static/img"
                    }
                }
            });

打包后包大小減少了0.2M,效果不大,但是對圖片處理更明顯的優(yōu)點(diǎn)是減少http請求以及在圖片渲染過程中的性能提升。

最終效果

image.png

以上方式可使項(xiàng)目在花費(fèi)較小時(shí)間成本的情況下讓性能有較大提升,如對性能還有更高要求,仍有很多方式可進(jìn)一步優(yōu)化。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容