臃腫項目優(yōu)化

前言

在項目開發(fā)的過程中對項目做過一些優(yōu)化,例如對項目結(jié)構(gòu)、模塊劃分做了明確的定義。但是,項目打包后的體積卻依然有78M、編譯需要30-60S(電腦都要跑爆炸)、多個龐大模塊混雜在一個項目當中。下面就來說說優(yōu)化的點吧。。

常規(guī)優(yōu)化

體積

從打包后的文件大小來看,圖片等資源30+M、js部分30+M,這些文件的大小實在是驚人,所以有了以下的操作:

1、 靜態(tài)資源遷移oss

明明有oss靜態(tài)服務器,前端同學也沒有用起來(匪夷所思),然后就把圖片、字體等資源遷移到了oss,然后刪除了一部分沒有在使用的資源(體力活,大概率不會有人來做了)

2、 webpack-bundle-analyzer

資源處理完了,使用webpack-bundle-analyzer分析一下js部分,大量插件被打包編譯,占了相當大一部分體積,將部分大且不經(jīng)常變動插件vue、vuex、element-uivue-router、moment改用cdn引入并配置externals

3、 關閉sourceMap

4、部分大型json類文件

從打包結(jié)果分析來看,一個js文件有500+KB,一看是關于地區(qū)的json數(shù)據(jù)

這樣處理完畢包大概還有個6+m,沒有處理的有echartslodash等,由于項目中有大量的按需引入,即使配置了externals也沒用,時間也不允許(畢竟抽空做一點是一點),即使如此包也已經(jīng)縮小了十倍

編譯時間

常規(guī)編譯時間優(yōu)化,基本都是配置webpack排除對一些文件的編譯,緩存編譯、多進程編譯等等,插件有hard-source-webpack-plugin、babel-plugin-dynamic-import-node、happypack等等一系列插件,我也都做了嘗試,有些許作用,但是我還是低估了項目的骨灰級程度,即使有了緩存、多進程也需要10+s,但這基本就是常規(guī)的編譯速度的優(yōu)化,還有一些小小的建議

1、 避免在入口文件大量引入資源

2、 盡量少的注冊全局狀態(tài) & 方法

3、 盡量封裝、少些無用代碼邏輯

按需編譯

說完了常規(guī)的,一起了解一下按需編譯,項目開發(fā)有一些公共模塊和無數(shù)個獨立的依賴公共部分的模塊

假設:

公共模塊 = main.js + plugins + store + router + 組件

那么:

模塊A = 公共模塊 + aPlugins + aStore + aRouter + a組件

模塊B = 公共模塊 + bPlugins + bStore + bRouter + b組件
復制代碼

如果開發(fā)A模塊時可以只編譯和A模塊相關的內(nèi)容,那編譯速度將會非常的快,以我目前正在優(yōu)化的項目,編譯時間由40+s縮短到了5s,相當可觀

但從描述上來講按需編譯可以看到多頁面、微前端的影子,但是成本是非常高的、技術方案相對比較重,同時需要團隊給予充分的時間、團隊成員也需要一定的技術能力,今天在分享一下按需編譯這個方案,目錄結(jié)構(gòu)如下

test
├── src
│   ├── main.js
│   ├── register.js
├── modules
│   ├── A
│   │  ├── store.js
│   │  ├── router.js
│   │  ├── index.js
│   ├── B
│   │  ├── store.js
│   │  ├── router.js
│   │  ├── index.js

復制代碼
// A - index.js
import Router from './router';
import Store from './store'

export default {
    router: Router,
    store: Store
};
// B - index.js
import Router from './router';
import Store from './store'

export default {
    router: Router,
    store: Store
};
復制代碼

指定編譯模塊

webpack-virtual-modules可以幫助生產(chǎn)虛擬模塊,然后根據(jù)環(huán)境變量通過require.context動態(tài)引入需要的模塊

// vue.config.js
// 借助webpack-virtual-modules生成虛擬模塊
const VirtualModulesPlugin = require('webpack-virtual-modules');
// 編譯模塊
const modules = process.env.npm_config_module || '';
// 是否是本地模塊編譯
const isModule = modules && process.env.NODE_ENV === 'development'
// 返回模塊虛擬
let buildModules = [];
if (isModule) {
    buildModules = modules.split(',').map((module, index) => `require.context("../modules/${module}", false, /index\.js$/)`);
}
module.exports = {
  configureWebpack: {
    plugins: [
      // 創(chuàng)建虛擬模塊
      new VirtualModulesPlugin({
          'node_modules/dynamic-modules.js': `module.exports = [${buildModules.join(',')}];`
      });
    ]
  }
}
復制代碼

動態(tài)添加信息

// test.js
export default (vue) => {
    //  獲取虛擬模塊數(shù)據(jù)
    let modules = require('dynamic-modules');
    // 遍歷
    for (const curModule of modules) {
        curModule.keys().map(key => {
            // 解析module
            const { router, store } = curModule(key).default;
            Object.keys(store).map(key => {
                // 動態(tài)添加store
                vue.$store.registerModule(key, store[key]);
            });
            // 動態(tài)添加router
            vue.$router.addRoutes(router);
        });
    }
}
// 在main.test.js
// mai.js
import test from './test'
const app = new Vue({ ... })
test(app)
復制代碼

此時當我們執(zhí)行npm run serve --module=A時,只會引入A模塊相關的信息,B模塊則不會進行編譯

這個方案更適合一些臃腫項目的優(yōu)化,時間、人力、技術要求成本均相對較低

優(yōu)點:成本低,改造快
缺點:針對本地開發(fā)

所以,有時間的話,還是進行一下微服務的嘗試

結(jié)語

神清氣爽

參考:
Webpack externals

「vue模塊化按需編譯,突破編譯瓶頸」實戰(zhàn)篇

用 Feature First 的方式管理前端項目復雜度

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

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

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