美文网首页
臃肿项目优化

臃肿项目优化

作者: cyh_1 | 来源:发表于2022-04-08 23:15 被阅读0次

    前言

    在项目开发的过程中对项目做过一些优化,例如对项目结构、模块划分做了明确的定义。但是,项目打包后的体积却依然有78M、编译需要30-60S(电脑都要跑爆炸)、多个庞大模块混杂在一个项目当中。下面就来说说优化的点吧。。

    常规优化

    体积

    从打包后的文件大小来看,图片等资源30+Mjs部分30+M,这些文件的大小实在是惊人,所以有了以下的操作:

    1、 静态资源迁移oss

    明明有oss静态服务器,前端同学也没有用起来(匪夷所思),然后就把图片、字体等资源迁移到了oss,然后删除了一部分没有在使用的资源(体力活,大概率不会有人来做了)

    2、 webpack-bundle-analyzer

    资源处理完了,使用webpack-bundle-analyzer分析一下js部分,大量插件被打包编译,占了相当大一部分体积,将部分大且不经常变动插件vuevuexelement-uivue-routermoment改用cdn引入并配置externals

    3、 关闭sourceMap

    4、部分大型json类文件

    从打包结果分析来看,一个js文件有500+KB,一看是关于地区的json数据

    这样处理完毕包大概还有个6+m,没有处理的有echartslodash等,由于项目中有大量的按需引入,即使配置了externals也没用,时间也不允许(毕竟抽空做一点是一点),即使如此包也已经缩小了十倍

    编译时间

    常规编译时间优化,基本都是配置webpack排除对一些文件的编译,缓存编译、多进程编译等等,插件有hard-source-webpack-pluginbabel-plugin-dynamic-import-nodehappypack等等一系列插件,我也都做了尝试,有些许作用,但是我还是低估了项目的骨灰级程度,即使有了缓存、多进程也需要10+s,但这基本就是常规的编译速度的优化,还有一些小小的建议

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

    2、 尽量少的注册全局状态 & 方法

    3、 尽量封装、少些无用代码逻辑

    按需编译

    说完了常规的,一起了解一下按需编译,项目开发有一些公共模块和无数个独立的依赖公共部分的模块

    假设:
    
    公共模块 = main.js + plugins + store + router + 组件
    
    那么:
    
    模块A = 公共模块 + aPlugins + aStore + aRouter + a组件
    
    模块B = 公共模块 + bPlugins + bStore + bRouter + b组件
    复制代码
    

    如果开发A模块时可以只编译和A模块相关的内容,那编译速度将会非常的快,以我目前正在优化的项目,编译时间由40+s缩短到了5s,相当可观

    但从描述上来讲按需编译可以看到多页面微前端的影子,但是成本是非常高的、技术方案相对比较重,同时需要团队给予充分的时间、团队成员也需要一定的技术能力,今天在分享一下按需编译这个方案,目录结构如下

    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可以帮助生产虚拟模块,然后根据环境变量通过require.context动态引入需要的模块

    // 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: [
          // 创建虚拟模块
          new VirtualModulesPlugin({
              'node_modules/dynamic-modules.js': `module.exports = [${buildModules.join(',')}];`
          });
        ]
      }
    }
    复制代码
    

    动态添加信息

    // test.js
    export default (vue) => {
        //  获取虚拟模块数据
        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 => {
                    // 动态添加store
                    vue.$store.registerModule(key, store[key]);
                });
                // 动态添加router
                vue.$router.addRoutes(router);
            });
        }
    }
    // 在main.test.js
    // mai.js
    import test from './test'
    const app = new Vue({ ... })
    test(app)
    复制代码
    

    此时当我们执行npm run serve --module=A时,只会引入A模块相关的信息,B模块则不会进行编译

    这个方案更适合一些臃肿项目的优化,时间、人力、技术要求成本均相对较低

    优点:成本低,改造快
    缺点:针对本地开发

    所以,有时间的话,还是进行一下微服务的尝试

    结语

    神清气爽

    参考:
    Webpack externals

    「vue模块化按需编译,突破编译瓶颈」实战篇

    用 Feature First 的方式管理前端项目复杂度

    相关文章

      网友评论

          本文标题:臃肿项目优化

          本文链接:https://www.haomeiwen.com/subject/jisusrtx.html