Skip to content

In some cases, the Hermes bundler produces a larger bundle with Esbuild than with Metro. #3361

Closed
@Augustach

Description

@Augustach

What happened?

Due to certain esbuild optimizations, Hermes generates more bytecode compared to the standard Metro bundle.

It hepens for me with the folowing case:
I use styled-components and react-native-gesture-handler and found that then more I have react-native-gesture-handler components wrapped into styled the more my hermes output bundle.

It seems the problem not in the styled-components and react-native-gesture-handler themself but more esbuild and hermes.

The problem can be boiled down to the following code:

// TouchableOpacity.tsx
let Reanimated;

try {
    Reanimated = require('react-native-reanimated');
}  catch (e) {
    Reanimated = undefined;
}

export const TouchableOpacity = ({ children }) => {
    Reanimated.useSharedValue(0);
    return children;
};

// index.tsx
const { TouchableOpacity } from './TouchableOpacity'

const styled = (Component: React.ComponentType) => (styles: any) => {
    return (props: any) => <Component {...props} style={styles} />;
};

// input
const Comp = styled(View)``;

// output
// var _a;
// const Comp = styled(View)(_a || (_a = null));

It seems that the combination of _a || (_a = null) and (this part in the react-native-gesture-handler lib ) are contributing to the large bundle size.

Affected Package

@rnx-kit/metro-serializer-esbuild

Version

0.2.0

Which platforms are you seeing this issue on?

  • Android
  • iOS
  • macOS
  • Windows

System Information

System:
  OS: macOS 14.5
  CPU: (10) arm64 Apple M1 Pro
  Memory: 1.89 GB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.7.0
    path: ~/.asdf/installs/nodejs/22.7.0/bin/node
  Yarn:
    version: 3.6.4
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.8.2
    path: ~/.asdf/plugins/nodejs/shims/npm
  Watchman: Not Found
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.5
      - iOS 17.5
      - macOS 14.5
      - tvOS 17.5
      - visionOS 1.2
      - watchOS 10.5
  Android SDK:
    API Levels:
      - "30"
      - "31"
      - "32"
      - "33"
      - "34"
    Build Tools:
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 33.0.1
      - 33.0.2
      - 34.0.0
    System Images:
      - android-23 | Google APIs ARM 64 v8a
      - android-29 | Google APIs ARM 64 v8a
      - android-30 | Google APIs ARM 64 v8a
      - android-31 | ARM 64 v8a
      - android-31 | Google APIs ARM 64 v8a
      - android-31 | Google Play ARM 64 v8a
      - android-32 | Google APIs ARM 64 v8a
      - android-33 | Google APIs ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2024.1 AI-241.18034.62.2411.12169540
  Xcode:
    version: 15.4/15F31d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
  Ruby:
    version: 3.0.3
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.75.3
    wanted: 0.75.3
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: Not found
  newArchEnabled: false

Steps to Reproduce

  1. Clone https://github.com/Augustach/esbuild-hermes-issue
  2. Run the script yarn copy-modules. This will generate 1000 copies of the ./src/template.tsx file.
  3. Run ESBUILD=true yarn build to create the esbuild bundle.
  4. Check the size of the ./output/index.android.bundle.hrs Hermes bundle.
  5. Run ESBUILD=true yarn build to create the metro bundle.
  6. Check the size of the ./output/index.android.bundle.hrs Hermes bundle.

Expected Result (ER): The size of the esbuild bundle should be less than or equal to the size of the Metro bundle.

Actual Result (AR): The size of the esbuild bundle (~2.7MB) is much larger than the bundle (~1.3MB) produced by Metro.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions