Parcel: Why the production bundle size is significantly larger that create-react-app

Created on 9 Apr 2019  路  11Comments  路  Source: parcel-bundler/parcel

I did a very simple experiment with the following settings

index.html (used for parcel-bundler only as create-react-app creates one automatically)

<html>
<body>
  <div id="root"></div>
  <script src="./index.js"></script>
</body>
</html>

index.js (also used in the project initialized with create-react-app)

import React from 'react'
import ReactDOM from 'react-dom'
import { FaBeer } from 'react-icons/fa'

const App = () => (
  <h1>
    Let's have some <FaBeer />!
  </h1>
)

ReactDOM.render(<App />, document.getElementById('root'))

./node_modules/.bin/parcel --version
1.12.3
./node_modules/.bin/parcel build index.html
parcel-build

While in a separate project initialized with create-react-app (2.1.8), the bundle size is way much smaller
cra-build-after-gzip

Without gzip:
cra-build

Nodejs version: 8.14.1
OS: Mac OSX Mojave

Can someone tell me why the bundle size difference is so significant? Are there any options I can use to improve/reduce the bundle size using parcel?

Bug 馃尦 Tree Shaking

All 11 comments

Tree shaking (parcel build --experimental-tree-shaking) should do precisely that. But there are (at least two issues):

  • react-icons has index.mjs and index.js in their react-icons/fa folder. To use the modern ES6 code suitable for treeshaking index.mjs needs to be preferred over index.js (this is quite an uncommon way of doing this). You can work around this by using import { FaBeer } from 'react-icons/fa/index.mjs'.
  • The bigger issue is that Parcel's treeshaking algorithm doesn't understand that exports like these can be shaken (currently, the second statement prevents that):
export var Fa500px = function (props) {
  return /*...*/;
};
Fa500px.displayName = "Fa500px"; // <--------------------
  • Furthermore, some weird Babel bug (I suspect) is currently breaking React builds using tree shaking: #2859



Discussion regarding bundle size in react-icons: https://github.com/react-icons/react-icons/issues/154

Thanks @mischnic for the quick response however I am getting

error: unknown option `--experimental-tree-shaking'

I am using version 1.12.3. Please advise.

Ok I found out the option is actually --experimental-scope-hoisting but it didn't help to reduce the bundle size much (using mjs import), I guess as @mischnic has already pointed out in the second problem of react-icons module, this bundle size issue won't be fixed until someone do something about react-icons or parcel-bundler, I am saying this is because create-react-app got it right.

Ok I found out the option is actually --experimental-scope-hoisting

Sorry, I always mix up these terms.
The rest of your comment is correct.

Sorry, I always mix up these terms.

No worries, thanks for helping out.

I'm keeping this open because

export var Fa500px = function (props) {
  return /*...*/;
};
Fa500px.displayName = "Fa500px";

is probably a common pattern and should be supported (at least this simple case).

is probably a common pattern and should be supported (at least this simple case).

That would be great. I am struggling with this particular react-icons module at the moment and it doesn't make sense if I have to switch back to CRA just to keep the bundle size down.

Thanks @devongovett for making the changes. When will this update become available? At the moment the version of parcel-bundler stays at 1.12.3.

@devongovett Has parcel been tested out for tree-shaking react-icons? I just tried to update parcel to the latest version and the problem still persists.

@JulienDemarque I just tested this with the current Parcel 2 build and doing import { FaBeer } from 'react-icons/fa' will indeed only include that single icon. (Not in Parcel 1.x.x)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidnagli picture davidnagli  路  3Comments

philipodev picture philipodev  路  3Comments

will-stone picture will-stone  路  3Comments

oliger picture oliger  路  3Comments

donaldallen picture donaldallen  路  3Comments