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 while bundling #227

Closed
adnaan1703 opened this issue Aug 23, 2018 · 17 comments
Closed

Tree shaking while bundling #227

adnaan1703 opened this issue Aug 23, 2018 · 17 comments

Comments

@adnaan1703
Copy link

Is it possible anyhow to implement tree shaking during bundling.

Suppose I have a file say greetings.js:

export const sayHi = (name) => {return `Jarvis says hi to ${name}`};
export const sayBye = (name) => {return `Jarvis says bye to ${name}`};

Now if in my project I am only using sayHi then I want sayBye to be removed from the final bundle which is currently not the case.
Is it possible anyhow to implement this (even if I had to do changes in the config file for the metro bundler).

@rafeca
Copy link
Contributor

rafeca commented Aug 28, 2018

Metro currently does not support tree shaking based on module import/export. @mjesun is currently adding first-class support for Metro to understand them and this will eventually allow us to do tree shaking.

Stayed tuned! 😃

@ghost
Copy link

ghost commented Nov 14, 2018

any outcome on tree-shaking ? Looking forward to that.

@karanjthakkar
Copy link
Contributor

@rafeca Now that we have experimental support for import/export inside metro, is tree shaking now available out of the box or is there work going on to support it? Anything that we can help with to make this possible?

@rafeca
Copy link
Contributor

rafeca commented Nov 27, 2018

@karanjthakkar : we're planning to implement some sort of tree shaking (or better said, minification of code based on the es6 module information) during H1 2019.

Based on our internal tests, the most impactful minification in terms of bundle size that can be done is to minify the import/export names, so for example:

// bar.js
export const ANY_VARIABLE_NAME = 'value';
// foo.js
import {ANY_VARIABLE_NAME} from './bar';
console.log(ANY_VARIABLE_NAME);

would get minified to:

// bar.js
exports.a = 'value';
// foo.js
console.log(r('./bar').a);

Afterwards, we're going to be able to do dead code elimination based on the exported values that are not being used anywhere

@camdagr8
Copy link

Any movement or resolution on this?

@aleclarson
Copy link
Contributor

Is this still slated for H1 2019?

@sunnylqm
Copy link
Contributor

sunnylqm commented May 18, 2019

@Jeevan-Kishore
Copy link

Is it supported yet?

@Mitsichury
Copy link

Hi ! Any news ?

@vrgimael
Copy link

Seems that's rather late

@neiker
Copy link

neiker commented Feb 6, 2020

Its february 2020, brexit happened but not this.

@cpojer
Copy link
Contributor

cpojer commented Feb 7, 2020

@rafeca and @mjesun have since left Facebook. We are not actively working on tree shaking at Facebook and are exploring other more promising ways to keep our app size small.

If you are using Metro for React Native, it is unlikely that tree shaking will have a major impact on your applications size or behavior. If you are looking for size improvements, consider compressing the JS bundle that you ship with your app. If you are looking for performance improvements, there are likely many other things (like shipping Hermes and bytecode) that will have a large impact.

I'll close this as wontfix now but we will accept contributions towards tree shaking – and I'm accepting your job applications if you wanna work on this kinda stuff at Facebook London :)

@TheEhsanSarshar
Copy link

TheEhsanSarshar commented Sep 1, 2021

I think https://github.com/callstack/repack supports tree shaking. you can use it instead of metro

what is repak:

A Webpack-based toolkit to build your React Native application with full support of Webpack ecosystem.

@matthew-dean
Copy link

It's disappointing that Facebook's position is essentially, "bundling the entire import probably won't that much bloat, or add that much performance degradation to your app".

True (maybe), but why not just... not add things that aren't needed? Tree-shaking is an expected feature of any JS bundler, and not having tree shaking violates the Law of Least Surprise. If we use 1 function in, say, a giant hooks library with 1,000 hooks, we expect only that 1 function to show up in our app. If Metro can't provide this, then IMO Metro should not be in the business of bundling and should pair with Vite, Webpack, or other such bundlers to find a solution for React Native devs.

@adnaan1703
Copy link
Author

adnaan1703 commented Nov 19, 2022

Totally agree. The smaller bundle can still be valid even though we performed compression and backed it with Hermes. Currently, we are sending the bundle over HTTP with brotli compression and the underlying engine is Hermes for better performance but that doesn't rule out the use case for tree shaking. Also, I believe folks here undermine the improvement one can get with tree shaking.

When I raised this issue, Haul (predecessor of repack) solved this issue by using webpack. At that time we saw an improvement of around ~49.64% of bundle size.

  • bundle size via metro: 505.84KB
  • bundle size via haul without tree shaking: 537.75KB
  • bundle size via haul with tree shaking: 254.74KB
    Bundle size improvement: haul w/ tree shaking vs metro -> 49.64% gain.
    *This was 2018.

We couldn't go to production with Haul because of a lack of community support and also the bundle it spits breaks our internal system. Our internal diffing logic would have needed overall changes. Also, using scripts to change haste-dependent libraries dynamically seems kind of a hack and is a bit dangerous to send in production.

But now I think we have multiple solutions out there:

  • esbuild with custom tree-shaking plugin
  • repack

Since these tools are now available, it is bound that users with advanced bundling needs will move away from Metro.

@kelset
Copy link
Contributor

kelset commented Nov 21, 2022

btw for those of you using Metro and wanting tree shaking, over at MSFT we have developed a plugin for Metro to basically rely on esbuild for treeshaking: https://github.com/microsoft/rnx-kit/tree/main/packages/metro-serializer-esbuild (guide here: https://microsoft.github.io/rnx-kit/docs/guides/bundling#tree-shaking)

We already use it in prod on a couple projects and saw good bundle size improvements

@mannoeu
Copy link

mannoeu commented Jul 26, 2023

Too bad... Ignoring real cases where Tree Shaking is necessary

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