closertb / closertb.github.io

浏览issue 或 我的网站,即可查看我的所有博客
https://closertb.site
32 stars 0 forks source link

从24M到1M: 一个react+antd后台系统构建打包历程 #30

Open closertb opened 5 years ago

closertb commented 5 years ago

写于: 2019-03-07

虽然在工作中用react+antd写页面写了一年,但从来没自己去认认真真配置一个webpack,去分析去优化自己打出的包。在工程化成熟或者大点的公司,都有自己的打包工具,所以自己工作中很少去琢磨这些。为了试一下写出的组件库(antd-doddle)性能,就尝试自己去写一个webpack构建,真的是吓了自己一跳,流水账(tu)开始。

从npm run dev开始

打包工具:webpack4 + babel6

开始前,大概说一下项目内容。项目基于react+react-router+antd+antd-doddle,自己日常在这个项目做一些技术验证与demo,就4个页面。组成如下:

  <Content style={{ margin: '24px 16px', padding: 24, background: '#fff', minHeight: 280 }}>
    <Switch>
      <Route exact path={menus.home.path} component={Home} />
      <Route exact path={menus.renderProps.path} component={ExampleTable} />
      <Route exact path={menus.hoc.path} component={Hoc} />
      <Route exact path={menus.learnTest.path} component={LearnTest} />
    </Switch>
  </Content>

页面js与公共(node_modules引用)js使用splitChunks分开打包。npm run dev,结果如下图,async.bundle.js大小24M,有点惊人的大。 image

打包工具:webpack4 + babel7
image

开始正题,npm run build

development与production

由于webpack在(mode)模式development与production还是有很大区别,当我直接将mode从development变成production,再运行npm start。打包大小还是有明显的变化,同时也报了三个警告,包体积大于244kb

image 打包大小从24M缩减到17M,由于run start是启用的webpack-dev-server来构建的,所以对应的production模式默认启用UglifyJsPlugin是无效的,但是可以手动去加入这段配置,然后打包大小能看到直线下降到3.25M,见下图

  optimization: {
    minimizer: [
      new UglifyJsPlugin()
    ],
    splitChunks: {
      name: 'async',
      minSize: 30000,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          chunks: 'all'
        },
      }
    }
  }

image

production模式构建

以上其实都是在用webpack-dev-server构建,当用webpack去构建时,然后npm run build,结果是这样的:

image 压缩后大小已经减小到2.6M,还是有实质的进步,然后通过BundleAnalyzerPlugin这个插件看包的构成,会发现antd,antd-doddle,moment占了绝大多数的空间。
image 恰好我知道moment虽然不支持按需打包,由于支持了多语言,所以省去无用的语言选项,就可以有明显的优化,所以使用ContextReplacementPlugin这个插件,并加上只匹配中文的筛选,如下所示:

    new webpack.ContextReplacementPlugin(
      /moment[/\\]locale$/,
      /zh-cn/,
    )

打包体积由2.6减少到2.3M。 image 当一个一个浏览完包的构成时,大小组成是这样的:

image

babel6升到babel7,修改一下配置。然后再运行npm run build, 结果如下:

image 当一个一个浏览完包的构成时,大小组成是这样的:

image

babel6到babel7,到底发生了什么

看到这种优化的效果真的让我惊喜与惊讶,但究竟是什么带来了这种变化更让我更好奇。还没抓到核心的区别,有清楚的,请指点一下,怎么避免js公共函数的重复注入,怎么来优化编译来完美对接后面webpack打包的?想往外去看看大神们都什么意见,可特殊时期,我的梯子被折断了(衰)。

文章提到的项目地址:webpack打包,master分支是对应babel6,roadhg分支是对应babel7

相关文章收集:

  1. 使用代码拆分减少JavaScript负载
  2. Mysterious SplitChunks Plugin
  3. 将你的构建效率提速翻倍