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 构建优化 #13

Open
shaozj opened this issue Dec 23, 2016 · 0 comments
Open

webpack 构建优化 #13

shaozj opened this issue Dec 23, 2016 · 0 comments

Comments

@shaozj
Copy link
Owner

shaozj commented Dec 23, 2016

两个问题

  1. 包体积过大
  2. 打包速度太慢

优化1 webpack.DllPlugin

能加快打包速度,减小自身业务代码打包后的体积,但代码总体积(包含了第三方库)反而增大

项目中我们要将第三方库的代码单独打包,一般采用的方式是 webpack.optimize.CommonsChunkPlugin 这个插件。

entry: {
 vendor: ['react', 'react-dom'] // 类库
};
   
new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  filename: 'vendor.js',
  minChunks: Infinity
}),

然而,用这种方式,每次我们重新构建代码时,vendor 的代码都要重新构建,从而使得构建的速度变慢。

webpack.DllPlugin 就可以解决这个问题,将第三方库事先编译为dll库,之后构建项目自身源码时,就不许要重新构建dll库中的代码。

首先,我们需要编写 webpack.dll.config.js 。

const path = require('path');
const webpack = require('webpack');
	
module.exports = {
  entry: {
    vendor: ['react', 'react-dom', 'antd']
  },
  output: {
    path: path.join(__dirname, 'build'),
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, 'build', '[name]-manifest.json'),
      name: '[name]_library'
    })
  ]
};

其实,webpack 中的插件也都可以用在 webpack.dll 配置文件中。

执行 webpack --config webpack.dll.config.js 后,即可在 build 目录下找到生成的 dll bundle 和对应的 manifest 文件。

> webpack --config webpack.dll.config.js

Hash: 674d064bed0bcc476713
Version: webpack 1.14.0
Time: 4349ms
        Asset     Size  Chunks             Chunk Names
vendor.dll.js  3.59 MB       0  [emitted]  vendor
   [0] dll vendor 12 bytes {0} [built]
    + 913 hidden modules

然后,我们在 webpack.config.js 中配置 DLLReferencePlugin 插件。

plugins: [
new webpack.DllReferencePlugin({
  context: __dirname,
  manifest: require('./build/vendor-manifest.json')
})
]

在 html 中,需要手动引入 dll 库

<script src="/build/vendor.dll.js"></script>

性能对比

首次构建:(build)
采用 CommonsChunkPlugin :

Hash: 6ade5ef99f806b597685
Version: webpack 1.14.0
Time: 13349ms
                    Asset     Size  Chunks             Chunk Names
program-list/index.js.map  18.7 kB       2  [emitted]  program-list/index
           index/index.js  26.2 kB       0  [emitted]  index/index
    program-list/index.js  19.3 kB       2  [emitted]  program-list/index
    theme-manage/index.js   622 kB       3  [emitted]  theme-manage/index
                vendor.js  1.43 MB       4  [emitted]  vendor
       index/index.js.map  19.3 kB       0  [emitted]  index/index
   new-theme/index.js.map   499 kB       1  [emitted]  new-theme/index
       new-theme/index.js   446 kB       1  [emitted]  new-theme/index
theme-manage/index.js.map   727 kB       3  [emitted]  theme-manage/index
            vendor.js.map  1.71 MB       4  [emitted]  vendor
               index.html  2.45 kB          [emitted]  
           new-theme.html  2.46 kB          [emitted]  
        program-list.html  2.47 kB          [emitted]  
        theme-manage.html  2.47 kB          [emitted]  

采用 DllPlugin :

Hash: 6f2755df167fdbf28a55
Version: webpack 1.14.0
Time: 8209ms
                    Asset     Size  Chunks             Chunk Names
program-list/index.js.map  10.4 kB       2  [emitted]  program-list/index
           index/index.js  26.1 kB       0  [emitted]  index/index
    program-list/index.js    12 kB       2  [emitted]  program-list/index
    theme-manage/index.js  48.4 kB       3  [emitted]  theme-manage/index
                vendor.js   303 kB       4  [emitted]  vendor
       index/index.js.map  19.3 kB       0  [emitted]  index/index
   new-theme/index.js.map  99.5 kB       1  [emitted]  new-theme/index
       new-theme/index.js   111 kB       1  [emitted]  new-theme/index
theme-manage/index.js.map  39.5 kB       3  [emitted]  theme-manage/index
            vendor.js.map   358 kB       4  [emitted]  vendor
               index.html   2.5 kB          [emitted]  
           new-theme.html  2.51 kB          [emitted]  
        program-list.html  2.52 kB          [emitted]  
        theme-manage.html  2.52 kB          [emitted]  

可以看到,用 DllPlugin 能比 CommonsChunkPlugin 约5s。这里的例子是一个多页面构建的例子。
注意,此处我们虽然看到 DllPlugin 打包出来的文件要比 CommonsChunkPlugin 的小,但其实是我们把第三方库提取到了 vendor.dll.js 中的原因,加上 vendor.dll.js 中的文件,DllPlugin 打包总文件体积更大。

模块热加载(rebuild)
采用 CommonsChunkPlugin :

Hash: d8187730060863aecaad
Version: webpack 1.14.0
Time: 2478ms
                               Asset      Size  Chunks             Chunk Names
6ade5ef99f806b597685.hot-update.json  36 bytes          [emitted]  
                      index/index.js   26.2 kB       0             index/index
               program-list/index.js   19.3 kB       2             program-list/index
               theme-manage/index.js    622 kB       3             theme-manage/index
                           vendor.js   1.43 MB       4  [emitted]  vendor
1.6ade5ef99f806b597685.hot-update.js   6.41 kB       1  [emitted]  new-theme/index
                  new-theme/index.js    446 kB       1  [emitted]  new-theme/index
                  index/index.js.map   19.3 kB       0             index/index
           program-list/index.js.map   18.7 kB       2             program-list/index
           theme-manage/index.js.map    727 kB       3             theme-manage/index
              new-theme/index.js.map    499 kB       1  [emitted]  new-theme/index
1.6ade5ef99f806b597685.hot-update.js.map   4.41 kB       1  [emitted]  new-theme/index
                       vendor.js.map   1.71 MB       4  [emitted]  vendor

采用 DllPlugin :

Hash: ca95bad33ad492f0a11b
Version: webpack 1.14.0
Time: 1005ms
                                   Asset      Size  Chunks             Chunk Names
    456baae3287b91efa0d4.hot-update.json  36 bytes          [emitted]  
                          index/index.js   26.1 kB       0             index/index
                   program-list/index.js     12 kB       2             program-list/index
                   theme-manage/index.js   48.4 kB       3             theme-manage/index
                               vendor.js    303 kB       4  [emitted]  vendor
    1.456baae3287b91efa0d4.hot-update.js    6.4 kB       1  [emitted]  new-theme/index
                      new-theme/index.js    111 kB       1  [emitted]  new-theme/index
                      index/index.js.map   19.3 kB       0             index/index
               program-list/index.js.map   10.4 kB       2             program-list/index
               theme-manage/index.js.map   39.5 kB       3             theme-manage/index
                  new-theme/index.js.map   99.5 kB       1  [emitted]  new-theme/index
1.456baae3287b91efa0d4.hot-update.js.map   4.41 kB       1  [emitted]  new-theme/index
                           vendor.js.map    358 kB       4  [emitted]  vendor

追求极致体验,dll 值得拥有。

另外还需注意到的一点是,antd 这个包非常大,大概有 2.6m,用 dll 的方式,就一次把整个antd 的包都打入 vendor.dll.js 中,使得 vendor.dll.js 非常大。这在开发环境时,为了追求打包速度,可以不考虑包大小。在生产环境下,建议还是采用 antd 推荐的 babel 插件,做按需加载处理,从而减小包的总大小

优化2 HappyPack

配置:

const HappyPack = require('happypack');
	
plugins: [
    new HappyPack({
      id: 'jsx',
      threads: 4,
      loaders: ['react-hot', 'babel?' + JSON.stringify({
        presets: ['es2015', 'stage-0', 'react']
      })]
    })
]
    
loaders: [
	{
	    test: /\.(js|jsx)$/,
	    //loader: 'react-hot!babel-loader',
	    loaders: ['happypack/loader?id=jsx'],
	    include: [].concat(
	      config.additionalPaths,
	      [ path.join(__dirname, '/../src') ]
	    )
    }
]

采用 happypack 能进一步将构建时间从10s提升至5s。

以上两个优化都是优化了构建速度,然而并没能减小代码编译后包的体积大小,这是以后需要继续探索改进的地方。

参考文档:

  1. 开发工具心得:如何 10 倍提高你的 Webpack 构建效率
  2. webpack使用优化(基本篇)
  3. webpack使用优化(react篇)
  4. webpack 的 dll 功能
  5. 彻底解决Webpack打包性能问题
  6. 使用 webpack + react + redux + es6 开发组件化前端项目
  7. happypack github
  8. webpack 2.1 beta20 + happypack 多线程
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant