Skip to content

Externalize ReactTransitionGroup (fixes big file size)#474

Merged
eddywashere merged 4 commits intoreactstrap:masterfrom
balloob:fix-externalizing-transition-group
Jun 27, 2017
Merged

Externalize ReactTransitionGroup (fixes big file size)#474
eddywashere merged 4 commits intoreactstrap:masterfrom
balloob:fix-externalizing-transition-group

Conversation

@balloob
Copy link
Copy Markdown
Contributor

@balloob balloob commented Jun 22, 2017

Reactstrap bundle size jumped from 95kB to 335kB with the release of v4.6.0 (#472).

After observing the bundled output using source-map-explorer I noticed that React, ReactDOM and React Transition Group all three were part of the bundle! Visualized bundle.

This was introduced when upgrading the React Transition Group package in #399. The imports were updated to point at modules that live under the react-transition-group package. For example:

import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';

By importing a module under the package, Rollup no longer found a matching entry in the list of imports that should be treated as external. This resulted in Rollup including it in the bundle.

This PR fixes it by setting up the correct external entries for the React Transition Group package and the imports that we use. I have also added back the entries to the global list for React Transition Group that were removed in #399 so that UMD builds will work correctly when used together with the UMD builds of React Transition Group. Visualized bundle after the fix.

image

Fixes #472.

This PR also reverts #433. #433 worked around the wrong bundling by pointing at the lib folder. This is wrong because the lib folder contains individually transpiled files. By being individually transpiled, each file will contain a copy of the babel helpers that are used, resulting in each component being bigger than it should be.

@nathancahill
Copy link
Copy Markdown
Contributor

👍

@nathancahill
Copy link
Copy Markdown
Contributor

We should also add bundle size as a step in the build process, like this: https://github.com/developit/vhtml/blob/master/package.json#L13

@virgofx
Copy link
Copy Markdown
Collaborator

virgofx commented Jun 23, 2017

@balloob If the references to react-transition-group imported via ES6 imports instead of cherrypicking would we need the cherrypicked references ?

e.g. Change: import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; to import { CSSTransitionGroup } from 'react-transition-group';.

If so, I'd argue that's the more normalized solution (Updating the few locations that use the package) and then just leaving one single top level package global/exclude.

The older documentation referenced cherry picking but was recently updated to use proper ES imports:
https://github.com/reactjs/react-transition-group#high-level-api-csstransitiongroup

@balloob balloob force-pushed the fix-externalizing-transition-group branch from e06f2ce to b64cb82 Compare June 23, 2017 17:03
@balloob
Copy link
Copy Markdown
Contributor Author

balloob commented Jun 23, 2017

@virgofx good point. I have addressed your comments 👍

@balloob balloob mentioned this pull request Jun 23, 2017
@balloob
Copy link
Copy Markdown
Contributor Author

balloob commented Jun 23, 2017

@nathancahill I will leave that up to a future PR. Opened issue #475 to discuss it.

@balloob
Copy link
Copy Markdown
Contributor Author

balloob commented Jun 24, 2017

@TheSharpieOne You've commented variations of your comment at three different spots. I will respond to all of them here.

You state that every lib ever is pointing at unbundled files. However, React will ship bundled by Rollup as a single build for both development and production starting React 16: https://unpkg.com/[email protected]/index.js See this talk by one of the Facebook React maintainers at ReactEurope about how the size and load times both went down with 10%: https://youtu.be/djOc1EK07Tk?t=300

Since lib/index.js will import every component, there is no cherry picking going on. If you want to cherry-pick without using modules, you have to import from lib/Card.js etc, which is still very much possible. Importing lib/index.js however will contain everything as per the source. This means that importing lib/index.js is equivalent to the compiled bundle, except that the Babel helpers will be part of each individually transpiled file. Take for example lib/CardDeck.js, a third of the code is BabelHelpers: _extends, _interopRequireDefault, _objectWithoutProperties. This averages a 500 byte cost per file, which with 70 components results in 39kB extra being shipped to users of Reactstrap. That's a 42% increase over the compiled file size.

The warning was because the 4.6 bundle was broken and actually included the whole of React in the compiled bundle! #433 didn't fix it, it just hid the problem for npm users while still having a broken build for UMD users. This PR will fix the build again and no warning will be issued.

@TheSharpieOne
Copy link
Copy Markdown
Member

TheSharpieOne commented Jun 24, 2017

When with react 16, they generate cjs and umd, right now and with your changes there is only umd with reactstrap. React 16 doesn't reference the umd output in their package.json.
Maybe you need to create another file and point to that, just don't point to the umd output as that is most certainly wrong.
Since size is the main concern (not just simply not including dependencies which should not be included) take a look at cjs vs umd file sizes in react 16, at least a 10% different in output size.
They also have development builds which help users step through troubleshooting locally.

@balloob
Copy link
Copy Markdown
Contributor Author

balloob commented Jun 24, 2017

That can be tweaked by marking lodash.omit and lodash.tonumber as external for a CJS build. Would save us 10kB.

Feel free to submit that as a followup PR once this one has been merged.

This PR saves 240kB for UMD bundles and 29-39kB* for CommonJS bundles. On top of that the loading time will be faster due to the flat bundle that Rollup creates.

*: 39kB for only including the Babel helpers once. Up to 10kB of waste if consumer also depends on lodash.omit.

@balloob
Copy link
Copy Markdown
Contributor Author

balloob commented Jun 26, 2017

@TheSharpieOne I have reverted the change to main. No reason to delay fixing the ES/UMD bundles over a discussion about the CJS entrypoint.

@balloob
Copy link
Copy Markdown
Contributor Author

balloob commented Jun 26, 2017

#477 includes this PR and creates a CommonJS build without any dependency included.

@balloob balloob mentioned this pull request Jun 27, 2017
@eddywashere eddywashere merged commit c40b89f into reactstrap:master Jun 27, 2017
@balloob balloob deleted the fix-externalizing-transition-group branch June 27, 2017 17:04
TheSharpieOne added a commit to mkalish/reactstrap that referenced this pull request Jul 19, 2017
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

Successfully merging this pull request may close these issues.

File Size in 4.6.0 has jumped from 95kB to 335.6kB

5 participants