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

RemoteEntry file size increased by ~7x #2579

Open
5 tasks done
sudhakar-selva opened this issue Jun 4, 2024 · 14 comments
Open
5 tasks done

RemoteEntry file size increased by ~7x #2579

sudhakar-selva opened this issue Jun 4, 2024 · 14 comments

Comments

@sudhakar-selva
Copy link

sudhakar-selva commented Jun 4, 2024

Describe the bug

Noticed a substantial increase in remote-entry file size during our migration from v1 to v2 and observed this for our webpack-based application as well as the rsbuild one. It appears that most of the additional size is coming from the module federation SDK and runtime. Is this expected? How can we reduce the remote entry file size?

// rsbuild.config.ts
export default defineConfig({
  plugins: [
      pluginReact({
          swcReactOptions: {
              development: isDev,
              refresh: isDev,
          },
       }), 
      pluginStyledComponents(), 
      pluginBasicSsl()
  ],
  tools: {
    rspack(config, { addRules, appendPlugins }) {
      config.output!.uniqueName = 'unique_name'
      appendPlugins([
        new ModuleFederationPlugin({
          name: 'App',
          filename: 'remoteEntry.js',
          exposes: {
            //...
          },
          remotes: {
            // ...
          },
         /** Returns all dependencies from pkg.json and sets singleton for react*, react-router* and  couple other pkgs**/
          shared: getSharedDependencies(),
          manifest: false,
          dts: false,
        })
      ])

      return config;
    },
  }
});
Screenshot 2024-06-04 at 11 35 06 PM

Reproduction

Added build config in description - please let me know if further details required

Used Package Manager

yarn

System Info

System:
    OS: macOS 13.6.6
    CPU: (8) arm64 Apple M1 Pro
    Memory: 85.33 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
    Yarn: 1.22.19 - ~/node_modules/.bin/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm
    Watchman: 2023.11.06.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 125.0.6422.114
    Firefox: 117.0
    Safari: 17.5

Validations

@MadaraUchiha-314
Copy link
Contributor

@ScriptedAlchemy This is in line with some of the conversations we have been having. Externalizing the federation runtime is an option to reduce the bundle size.

Providing the external is by hosting it in a public/private CDN is the challenge.

I guess the @module-federation/runtime package can spit out single file builds which are in various formats like ESM, UMD, SystemJS etc.

I tried to do a quick check for this using esm.sh. Here's the PR: MadaraUchiha-314/rollup-plugin-module-federation#55

@ScriptedAlchemy
Copy link
Member

Yeah. We will work on making the runtime work similar to shared in the future. So if host is providing or has the runtime already the containers don't need to load theirs. After SSR lands for modernjs we will most likely take a closer look at how to reduce the payload size. Due to time we had to make some compromise as this is not a easy one to solve in a elegant way

@karthickshanmugam0689
Copy link

karthickshanmugam0689 commented Jun 15, 2024

Yes as a tool ModuleFedaration is awesome, but the size is too huge to use in a production build. We have a size limiter for our builds but now our bundle size is getting increased more than the set threshold limit.
An example where the bundle size is getting increased
Screenshot 2024-06-15 at 10 56 24

And the related bundle analysis by webpack-analyzer
Screenshot 2024-06-15 at 11 11 07

@ScriptedAlchemy
Copy link
Member

@karthickshanmugam0689 trust me I hear you. Will sync with the team next week and see what we can do about it.

My plan was to hold off on this task till I go to china this month, then we could all work on it in person.

I did take a look into it on one of my flights recently, I am able to half the artifact size with a few adjustments but I do need to find the best way to still make it easy for users to use and not introduce perf drag when users enable the features.

Let me sync with everyone and follow up on this. Im also not happy with the size but again we had to pick one or the other to get going. I appreciate the patience here, will make this a priority on my end but need to collaborate with my team about it and i know we have some big ticket items we really want to land

@ScriptedAlchemy
Copy link
Member

Okay I have found a possible solution here.

I can tell remotes to skip importing the runtime and instead create a remoteEntry that expects the runtime to be external / provided by the host.

If your host runtime is out of sync with the remotes, however, you will most likely break your application.

But if you can manage to keep them in sync, then this solution would work.

The alternative is to treat it like shared code with strict semver. But if anyone needs to load their own runtime you will have a much slower app startup than just loading an extra 20kb of code. establishing a HTTP call will take far longer than an already in-flight payload that a little larger.

@MadaraUchiha-314
Copy link
Contributor

MadaraUchiha-314 commented Jun 19, 2024

If your host runtime is out of sync with the remotes, however, you will most likely break your application.

It would be good to add in a console.warn or trigger a hook in such a case where we detect that the runtime of the host is incompatible with the runtime requested by the consumers.

It will also be good if a higher order entity (like a shell) has the ability to register/provide the runtime, just like we register a global runtime plugin

@sudhakar-selva
Copy link
Author

If your host runtime is out of sync with the remotes, however, you will most likely break your application.

This might help address the bundle size issue; however, it might add additional complexity, as we have to maintain module federation in sync with both the host and remotes.

Curious about v1 of module federation: did we always incur this cost? Instead of the federation runtime code being in the remote entry, was it in the webpack runtime?

Also, can we tree-shake unused modules from the SDK and runtime? We may not be able to share the runtime with other apps, but it might be worth the tradeoff. Could you please share recommended methods for maintaining the remote entry size small (apart from the module federation runtime)?

@karthickshanmugam0689
Copy link

In general additional hop might not be of a big concern though. runtime can be shared from host and not being eager here.

@zackarychapple
Copy link
Collaborator

Can you check if this is still the case with this being merged? #2818

@MadaraUchiha-314
Copy link
Contributor

MadaraUchiha-314 commented Aug 5, 2024

Can you check if this is still the case with this being merged? #2818

A version is not released to test. Additionally, I don't think it's going to help that much. The main issue is the runtime package not the utilities. If runtime uses utilities and that wasn't tree-shaken before, then it might be something, but not very hopeful with this change alone.

Update: According to @ScriptedAlchemy utilities is not supposed to be used: #2794 (comment)

@ScriptedAlchemy
Copy link
Member

Yeah utils is a dead package.

@karthickshanmugam0689
Copy link

Any inputs on this one as we really wanted this to be part of our code-base? But size is the only thing blocking us from using it.

@sudhakar-selva
Copy link
Author

https://module-federation.io/blog/hoisted-runtime.html

Looking forward to the Shareable Runtime to reduce remotes size.

@ScriptedAlchemy
Copy link
Member

ScriptedAlchemy commented Sep 30, 2024

I will work next on adding shareable runtime, now that the work for hoisted runtime is done.
You can track the progress on this PR for it.

#3018

If you have multiple entrypoints, then setting the federationRuntime to hoisted will already reduce the duplication across entrypoints.

If you are a next user - this is already enabled in nextjs

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

5 participants