Skip to content

Webpack 2: Larger Bundle Size in Stats Analysis Tool #1981

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

Closed
dtothefp opened this issue Feb 2, 2016 · 10 comments
Closed

Webpack 2: Larger Bundle Size in Stats Analysis Tool #1981

dtothefp opened this issue Feb 2, 2016 · 10 comments
Labels

Comments

@dtothefp
Copy link

dtothefp commented Feb 2, 2016

I was excited for Webpack 2 and Tree Shaking but upon implementing it into my application is seems to bloat the bundle by about 300kb. I can try to reproduce this in a smaller sample repo but for now I'll just show screenshots of my current application bundle size from generated stats. Here is a link to my generated stats and below are screenshots:

https://drive.google.com/folderview?id=0Bz7gMzxYFJb9cVc1dUdBZlpvZVE&usp=sharing

Webpack 1

webpack-1-stats-screen-shot

##### Webpack 2

webpack-2-stats-screen-shot

  const babelrc = `{
    "presets": ["react", "es2015-webpack", "stage-0"],
    "env": {
      "development": {
        "plugins": [
          "rewire",
          "transform-decorators-legacy",
          "typecheck",
          ["transform-runtime", {"polyfill": true}],
          ["react-transform",
            {
            "transforms": [{
              "transform": "react-transform-hmr",
              "imports": ["react"],
              "locals": ["module"]
            }, {
              "transform": "react-transform-catch-errors",
              "imports": ["react", "redbox-react"]
            }]
          }]
        ]
      },
      "production": {
        "plugins": [
          ["transform-runtime", {"polyfill": true}],
          "transform-decorators-legacy",
          "typecheck"
        ]
      }
    }
  }`;
@Globegitter
Copy link

@dtothefp Is that the unminified file? Only if you minify (i.e. add new webpack.optimize.UglifyJsPlugin() to plugins) you will get the tree-shaking effect.

And at least part of the reason why the unminified file is larger is because webpack adds annotations of which imports/exports are unused.

@dtothefp
Copy link
Author

dtothefp commented Feb 3, 2016

@Globegitter thanks for the heads up on Tree-Shaking and uglify plugin, I wasn't aware of that. I was not using the plugin because that destroys the stats visualization but I was using the uglify-loader which works on the module, not the bundle, level.

Unfortunately, using the uglify plugin still results in a 300kb bundle size increase in Webpack 2 vs Webpack 1. When I looked at my compiled code just using the uglify-loader I was able to see that about an extra 100 Webpack modules were added ie.

Webpack 1: last module

/* 741 */
/***/ function(module, exports, __webpack_require__, __webpack_module_template_argument_0__, __webpack_module_template_argument_1__) { //..

Webpack 2: last module

/***/ },
/* 837 */
/***/ function(module, exports, __webpack_require__) {

    __webpack_require__(461);
    module.exports = __webpack_require__(460);

I didn't have too much time to try and pinpoint this, but I'm wondering if it has to do with some shimming from node-libs-browser that updated to 1.0.0 in Webpack 2 vs 0.5.3 in Webpack 1. This is just a shot in the dark, but I am using some node config which I'm assuming is polyfilled through this module?

    node: {
      dns: 'mock',
      net: 'mock',
      fs: 'empty'
    }

Anyway, screenshots of bundle size are below

Webpack 1
screen shot 2016-02-03 at 11 57 58 am

Webpack 2 😢
screen shot 2016-02-03 at 11 56 14 am

@Globegitter
Copy link

@dtothefp not so sure, but also check out https://github.com/samccone/The-cost-of-transpiling-es2015-in-2016 which has a webpack 1 vs 2 example and the webpack 2 bundle is slightly smaller.

@ctrlplusb
Copy link

I am experiencing the same. Was equally excited by the treeshaking features, knowing that I use precious little of libraries such as ramda, but after the upgrade the resultant build was almost equivalent of my previous build size. UglifyJs and the new LoaderOptions plugins were both being used.

@vladshcherbin
Copy link

Same here, webpack 2 output file is larger than webpack 1.

@schmod
Copy link

schmod commented Apr 27, 2016

Experiencing the same thing here with a big Angular app.

Our code isn't written in a way that would benefit much from tree-shaking, but it appears that Webpack's native ES6 module support always produces code that is considerably more verbose than Babel's CJS transpiler.

If I use Babel to transpile my ES6 modules into CJS, Webpack 2's performance isn't quite as bad (but is still worse than Webpack 1.13.0).

The following simple script demonstrates my case nicely:

import angular from 'angular';
import moment from 'moment';

export default angular.module('foo', [])
.run(function(){
    window.foo = moment();
});

Using Webpack to "bundle" the above script (with the CommonsChunkPlugin splitting Angular & Moment into a separate chunk), the Webpack 2 consistently produces a larger bundle:

Webpack Version Babel Preset Unminified Size Minified Size Unminified vendor.js Minified vendor.js
Webpack 2.1.0-beta.6 babel-preset-es2015 595B 284B 1.65MB 358kB
Webpack 2.1.0-beta.6 babel-preset-es2015-webpack 1.44kB 360B 1.65MB 358kB
Webpack 1.13.0 babel-preset-es2015 584B 274B 1.32MB 214kB

Here's the webpack.config.js used for the above comparison. (The modifications I made between runs should be obvious from the description)

Webpack 2's ES6 transpilation appears to be adding some overhead to the test script above, and is slightly less efficient even when Babel does the CJS transformation for me. Somewhat surprisingly, the Angular/Moment bundle gets significantly larger when Bundled with Webpack 2.

If you click through on the above file sizes, you can see just how much more verbose Webpack 2's output can be. It seems like there are some relatively straightforward opportunities to make this more efficient for most common/simple cases...

@schmod
Copy link

schmod commented May 6, 2016

Another question that's surfaced while examining this issue:

Why doesn't Webpack "inline" modules that are only used once? A lot of rollup's advantages are derived from the fact that it does this...

Even if we only did this in simple cases (ie. a module that exports a string and nothing else), it seems like we could shave a few bytes off of most typical bundles.

@CreepGin
Copy link

Also getting a big size increase with webpack 2 (~26% increase from 0.9mb to 1.14mb). This is with the -p flag.

@schmod
Copy link

schmod commented Aug 23, 2016

I've added an update to my analysis above in #2873. For the test-case described above, Webpack 2.1-beta.21 is now producing consistently smaller bundles than Webpack 1.

I think we can close this ticket.

@sokra sokra closed this as completed Aug 25, 2016
@dtothefp
Copy link
Author

this is awesome @schmod thanks for digging in and keeping the issue up to date!

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

8 participants