Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack前端代码优化之旅 #7

Open
programmer-yang opened this issue Apr 16, 2018 · 3 comments
Open

webpack前端代码优化之旅 #7

programmer-yang opened this issue Apr 16, 2018 · 3 comments
Labels

Comments

@programmer-yang
Copy link
Owner

programmer-yang commented Apr 16, 2018

起因

最近接手了一个前端项目,由于之前前端开发人员比较多加上没有人很好的来约束管理,到我手上的时候已经变的比较恐怖,这里的恐怖主要指代码臃肿和体积庞大,随便改点东西,热加载都需要8秒左右的时间,在此基础上改需求已经异常难受,优化代码变的刻不容缓。

任务

简单列一下优化任务清单:

  1. 梳理第三方组件
  2. 使用DllPlugin优化开发环境
  3. 使用CommonsChunkPlugin优化生产环境

步骤 1

要完成这一步,我们要先分析一下当前代码的第三方组件使用情况,这里我推荐使用webpack-bundle-analyzer

yarn add webpack-bundle-analyzer

***.prod.js中添加

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
//...
plugins: [
  new BundleAnalyzerPlugin(),
]

然后运行编译命令,编译结束后本地会启一个服务并在浏览器中弹出一个页面,页面中就是当前编译后代码的组件使用情况,从中找出没用用且很大的组件,然后从代码中移除或注解

很多人在写代码的时候不会注意,就是只要你import的组件,不管是否使用,都会打包进去,切记开启no-unused-vars规则

这是个体力活儿,慢慢处理吧
当我完成这这一步的时候,我的项目已经从7mb的容量缩小到了3mb

步骤 2

我们代码已经比最开始清爽了很多,但我发现现在在开发的时候热加载还是4到5秒左右,还是不能忍受,所以我们现在要开始优化开发体验

webpack的组件dllplugin可以让你的热加载只编译业务部分,从而来大大提升热加载速度,这里我推荐使用autodll-webpack-plugin

yarn add autodll-webpack-plugin

然后在你的***.dev.js配置文件中加上

const AutoDllPlugin = require('autodll-webpack-plugin'); // dll
//...
plugins: [
  new AutoDllPlugin({
      inject: true, // will inject the DLL bundles to index.html
      filename: '[name].[hash].js',
      path: 'static/js',
      entry: {
        vendor: [
          'react',
          'react-dom',
          // 这里放步骤1中分析出来的比较大,但又必须使用的组件库
        ]
      }
    }),
]

完成这一步后这个项目的热加载速度已经降低到了3s以内,已经可以接受了

我的电脑年级比较大了,新电脑应该能到2s以内

步骤 3

我们来进行最后一步,优化此项目的线上表现
这里其实有几种思路,比如按需加载,但考虑到一些原因,这次的优化暂时不上按需,只是提取一下公共文件
这里我们要用到CommonsChunkPlugin
***.prodj.js

//...
plugins: [
  new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: module => {
        return module.resource && /node_modules/.test(module.resource)
      }
    }),
]

这里的意思是把node_modules下的所有包都提取到公共文件中
现在的webpack已经没有"boilerplatemanifest 代码可能在每次编译时都会变化"的问题,所以不用单独提取

总结

通过这3步,我在很短的时间内解决了当下这个项目的几个痛点,但优化的路还很长,而且优化永远是补救措施,更关键的还是从源头解决问题,比如整体团队的能力提升,整体代码质量的把控,都是需要很多精力去搞的事情,让我们一起加油吧

参考

DllPlugin
CommonsChunkPlugin
autodll-webpack-plugin
https://www.erichain.me/2017/07/11/2017-07-11-speeding-up-webpack-with-dllplugin/
creeperyang/blog#37

@programmer-yang
Copy link
Owner Author

步骤 3 中出现一个比较奇怪的bug,最终分析是因为这个写法会把业务代码的样式全部提取出去,所以这里要手动排除一下

new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: module => {
        if(module.resource && (/^.*\.(css|less|scss)$/).test(module.resource)) {
          return false;
        }
        return module.resource && /node_modules/.test(module.resource)
      }
    }),

@programmer-yang
Copy link
Owner Author

再说两句
后续的工作中发现一些问题,分析其原因还是一些开发人员对create-react-appantd理解不是很好,也许还有其他人在使用过程中也会有同样的困惑,这里记录下来,以便能帮到其他人

关于引入antd

这里其实能说的不多,最核心的就是一个关于antd样式的引入需要注意一下
antd官方介绍:关于使用create-react-app来构建项目
这里的核心是使用react-app-rewired来覆盖原来的默认react-app
然后在配置文件里添加

config = injectBabelPlugin(['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }], config);

这里需要说一下的就是在使用了eject命令后的项目
可能很多人在这种情况下就直接使用.babelrc来解决问题,这样没问题,但不优雅

因为这样你会覆盖原有的关于babel的配置(babel应该是优先用户的配置文件的),这种情况下你还要自己安装babel-preset-es2015 babel-preset-stage-1等等,所以说不优雅

正确的方式应该是这样的:package.json

"babel": {
    "plugins": [
      ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
    ],
    "presets": [
      "react-app"
    ]
  },

这是官方提供的添加babel配置的入口

关于打包后的大小

这里其实要说的不多,记录一下初始大小以便以后查看吧

// react
119K  4 27 10:25 main.14d7adfe.js
// react antd (Button)
143K  4 27 10:50 main.b85f62e5.js
// react antd (Button Modal)
179K  4 27 10:51 main.9f51c035.js
// react antd (Button Modal) react-router
226K  4 27 10:56 main.20227069.js

@dontdrinkmylemontea
Copy link

写得很赞。博主怎么不继续更了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants