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

Add tree-shaking to the metro bundling process #127

Closed
afoxman opened this issue Apr 12, 2021 · 3 comments
Closed

Add tree-shaking to the metro bundling process #127

afoxman opened this issue Apr 12, 2021 · 3 comments
Labels
feature: metro This is related to Metro

Comments

@afoxman
Copy link
Contributor

afoxman commented Apr 12, 2021

Tree-shaking is the practice of finding and excluding unused JS code when assembling a bundle file. It has been historically absent from Metro, despite several attempts to get it added over the years. A prototype implementation has recently gained traction, and should be the starting point for this work.

@tido64
Copy link
Member

tido64 commented Apr 14, 2021

I had a quick look at the prototype PR:

  • You can skip most of the PR, all the way to packages/metro-babel-transformer/src/index.js
    • The first 65 files are adding a test app
    • packages/metro-tree-shaking/ is where the interesting bits are
  • metro-transform-worker: An extra transformation was added here for some reason
    • I'm not sure why it couldn't reuse an existing one
  • metro-tree-shaking implements "module-level" tree shaking:
    1. First, gather all imports (see collectExports())
    • Exports of dependencies are reference counted
      • Example: A depends on B, increment ref count of all names exported of B
    • If the dependency has sideEffects: true, then the depending module also produces side effects
    1. Filter out ignored modules, and the ones that have sideEffects: true
    2. For every unused reference, traverse its dependencies and decrement the ref count
    • There's more stuff happening here that I can't quite decipher
    1. Finally, remove the unused ones
  • Some modules need to be explicitly ignored, such as Babel and react-native, because they provide utilities that are used by generated/injected code.

@tido64
Copy link
Member

tido64 commented Apr 20, 2021

Result from investigating Hermes' impact on bundle size when it comes to tree shaking:

lpc-android Size Delta
Haul 2 158 968 -
Haul → Hermes@0.4.3 1 961 778 -197 190 (-9%)
Haul → Hermes@0.7.2 1 942 512 -216 456 (-10%)
Metro 2 693 589 +510 882 (+24%)
Metro → Hermes@0.4.3 2 416 724 +257 756 (+12%)
Metro → Hermes@0.7.2 2 398 056 +239 088 (+11%)
lpc-ios Size Delta
Haul 1 947 250 -
Haul → Hermes@0.7.2 2 046 124 +98 874 (+5%)
Metro 2 684 661 +737 411 (+38%)
Metro → Hermes@0.7.2 2 391 184 +443 934 (+23%)

Setup:

  • Haul@0.19
    • { dev: false, minimize: true, namedModules: false }
  • Hermes
    • -O -emit-binary -fstrip-function-names -output-source-map
  • Metro@0.59
    • react-native bundle --dev false ...
    • babel.config.js: { disableImportExportTransform: true }
    • metro.config.js: { experimentalImportSupport: true }
    • Plugins: babel-plugin-lodash

@tido64 tido64 closed this as completed Apr 20, 2021
@tido64 tido64 reopened this Apr 20, 2021
@tido64
Copy link
Member

tido64 commented Jun 23, 2021

Addressed by #292.

@tido64 tido64 closed this as completed Jun 23, 2021
@tido64 tido64 added the feature: metro This is related to Metro label Jul 8, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature: metro This is related to Metro
Projects
None yet
Development

No branches or pull requests

2 participants