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

Tree-shaking doesn't seem to be working with latest Webpack #2859

Closed
mariuslazar93 opened this issue Apr 4, 2018 · 4 comments · Fixed by #2861
Closed

Tree-shaking doesn't seem to be working with latest Webpack #2859

mariuslazar93 opened this issue Apr 4, 2018 · 4 comments · Fixed by #2861

Comments

@mariuslazar93
Copy link

Do you want to request a feature or report a bug?
Bug. Repo to reproduce: https://github.com/mariuslazar93/algolia-instantsearch-test . We are only concered about the final bundle size, so just running npm install and npm run build-prod will generate a dist folder with the production files.

Bug: What is the current behavior?
I am trying to create a production build using Webpack 4.5.0 and make use of tree-shaking to remove the unimported widgets/connectors.

I'm only importing 3 widgets inside ./src/js/search.js (listed below too), but the generated bundle report shows that all the widgets and connectors are imported into the final (production) bundle.

import instantsearch from 'instantsearch.js/es';
import { searchBox, hits, pagination } from 'instantsearch.js/es/widgets';

I'm splitting the bundles into app.bundle.js, vendor.bundle.js (what comes from /node_modules) and runtime.bundle.js (webpack runtime). I've added the webpack-bundle-analyzer to generate the dependencies report of the bundles (as you can see in the image).

It also seems like the prod bundle ends up with a duplicated loadash library which adds up to the final size.

image

Bug: What is the expected behavior?
Only the imported widgets should show in the final bundle. Only one loadash library.

Bug: What browsers are impacted? Which versions?
Doesn't apply.

Bug: What is the proposed solution?
Seems like Webpack 4+ is using a sideEffect property in package.json which dictates if the unused code can be removed safely by the minifier (UglifyJS in this case). More on their docs: https://webpack.js.org/guides/tree-shaking/ . Not sure if this is the problem or not.

What is the version you are using? Always use the latest one before opening a bug issue.
Latest.

If I'm missing something please let me know.

@Haroenv
Copy link
Contributor

Haroenv commented Apr 4, 2018

I've been investigating this a bit over and saw significant improvements in the bundle size.

I also noticed that when I regenerated the package-lock.json in your repo, or if I used Yarn, lodash is only installed / included in the bundle once.

I'll be doing two PRs to this repo with this in mind

@Haroenv
Copy link
Contributor

Haroenv commented Apr 4, 2018

mariuslazar93/algolia-instantsearch-test#1 for updating your lockfile

Haroenv added a commit that referenced this issue Apr 4, 2018
Why is this done? see <https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free>

Long story short, modules can do crazy things, but if we don't do any polyfilling, we can opt into better behaviour

fixes #2859 as good as we can for now
@mariuslazar93
Copy link
Author

Awesome! Thanks for your work! The size is indeed noticeable 👍

Not sure if you guys are already using the ES6 modules for loadash and just importing the methods that you need, but if you don't, you can make even more improvements by using lodash-webpack-plugin and babel-plugin-lodash which will transform the importing syntax to be tree-shakable.

@Haroenv
Copy link
Contributor

Haroenv commented Apr 4, 2018

We should already be doing what’s necessary there, we just use a lot of Lodash in the helper (it’s very transformation-heavy and supports older browsers), so we can’t win a lot of size easy that way. It was investigated earlier. Thanks for the suggestion though!

bobylito pushed a commit that referenced this issue Apr 5, 2018
Why is this done? see <https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free>

Long story short, modules can do crazy things, but if we don't do any polyfilling, we can opt into better behaviour

fixes #2859 as good as we can for now
bobylito pushed a commit that referenced this issue Apr 9, 2018
<a name=2.7.0></a>
# [2.7.0](v2.6.3...v2.7.0) (2018-04-09)

### Bug Fixes

* pagination padding ([#2866](#2866)) ([e8c58cc](e8c58cc))
* **geosearch:** avoid reset map when it already moved ([#2870](#2870)) ([f171b8a](f171b8a))
* **removeWidget:** check for widgets.length on next tick ([#2831](#2831)) ([7e639d6](7e639d6))

### Features

* **connetConfigure:** add a connector to create a connector widget ([8fdf752](8fdf752))
* **routing:** provide a mechanism to synchronize the search ([#2829](#2829)) ([75b2ca3](75b2ca3)), closes [#2849](#2849) [#2849](#2849)
* **size:** add sideEffects false to package.json ([#2861](#2861)) ([f5d1ab1](f5d1ab1)), closes [#2859](#2859)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants