Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Investigate tree-shakeability of our umbrella fuels package #1460

Closed
nedsalk opened this issue Nov 27, 2023 · 6 comments
Closed

Investigate tree-shakeability of our umbrella fuels package #1460

nedsalk opened this issue Nov 27, 2023 · 6 comments
Assignees
Labels
chore Issue is a chore
Milestone

Comments

@nedsalk
Copy link
Contributor

nedsalk commented Nov 27, 2023

From this comment:

We could try variations with different usages simulating real-world case scenarios to see how tree-shakable things are.
One variation is the quickstart/scaffold PR that @Dhaiwat10 started (#1408)
Another is the wallet itself. (cc @FuelLabs/frontend)
There might be others as well.

For example, our demo-react-vite app has this import statement: import { BaseAssetId, encrypt, decrypt } from "fuels";, but the impact on bundle size is +187kB, which is too much for such simple imports.

@Torres-ssf Torres-ssf added chore Issue is a chore and removed settings labels Dec 8, 2023
@nedsalk nedsalk self-assigned this Dec 12, 2023
@arboleya arboleya added this to the Beetle milestone Dec 14, 2023
@nedsalk
Copy link
Contributor Author

nedsalk commented Dec 18, 2023

Currently as it is, our packages satisfy the main requirement of tree-shakeability, which is that we are generating ESM javascript. However, our packages suffer from three problems that cause suboptimal tree-shakeability:

  1. Having a dependency on a CommonJS package that's not tree-shakeable (e.g. semver, elliptic, bn.js)
  2. Depending on packages that are not optimally tree-shakeable or that export more than we need due to the way they're internally structured, whereas we can implement the functionality ourselves (e.g. ethers, graphql-request) ,
  3. Writing code that's not properly tree-shakeable (using large classes instead of functions, using enums where discriminated unions of strings can be used, static fields like FuelError.CODES don't tree-shake properly...)

The biggest bang for the buck would be solving the problems in the order above.
For a reference on the least tree-shakeable parts of the fuels package, you can take a look at #1461. In an ideal world, all of the @fuels-ts packages in that list would be zero, which would mean that they're fully tree-shakeable.

Other things worthy of mentioning:

  • We don't need to build cjs and iife modules because we're targeting node v18 and above, which has support for esm, and iife modules were traditionally built to not pollute the global namespace but esm modules have their own scope so that case is obsoleted.
  • Setting esModuleInterop to false in tsConfig.base.json might be helpful when getting rid of CommonJS dependencies. For example, it causes our semver imports to break.
  • We should maybe change the tsconfig.base.json fields module and moduleResolution to ES2022 and Bundler, respectively. This is to be explicit that we're aiming for ESM and not be bitten by some misconfiguration down the line.
  • Setting package.json's type property to module will tell node that the package should be built as ESM. If not specified, it'll build it like CommonJS. Still, it seems like our tsup settings override this in the format property because we are building ESM code.

@arboleya arboleya modified the milestones: 2 - Beetle, 1 - Salamander Dec 18, 2023
@arboleya
Copy link
Member

Cross-referencing with:

I experienced large bundle sized when building with fuels-ts, I'd consider having a CI check to ensure the way we have the sdk published can be properly tree shaken. This could be due to my bundler, but we should check to ensure it's not.


@arboleya
Copy link
Member

arboleya commented Dec 19, 2023

Thanks for your investigations so far. 🙏

Before deciding on a path forward, we should try assembling a table with:

  1. List of problematic dependencies
    • Do we have alternatives to them?
  2. List of problematic packages
    • How much KB would we save by re-working each?

The goal is to have a quick glance at the trade-off between effort x benefits before prioritizing anything.

Note

  1. iife might be useful for in-browser playground (or via CDN)
  2. We can't change things like moduleResolution yet because of the Wallet (using an old bundler)
  3. Changing the project to module could also break apps already using it (such as the Wallet)

@nedsalk
Copy link
Contributor Author

nedsalk commented Dec 19, 2023

  1. List of problematic dependencies - Do we have alternatives to them?

Listing the dependencies that I remember off the top of my head (not a final list):

  • semver - We are only using a subset of it that can be easily implemented internally. I easily did it with GitHub Copilot, lol.
  • ethers - We only use like four of their exports and it seems like we can just copy-paste the bare minimum that we need.
  • elliptic - We are only interested in secp256k1 from this package, which we could replace with the audited @noble/secp256k1.
  • bn.js - This is already a topic in Migrate bn.js to bignumber #1542.
  • graphql-request - it can be replaced with a simple fetch.

List of problematic packages - How much KB would we save by re-working each?

A lot of the issues related to tree-shakeability will be solved by fixing problematic dependencies. The packages that would most benefit from removing those dependencies are listed in #1461. We shouldn't spend time analyzing them until we solve the dependencies problem first because we won't know the state of our code properly until then. It's arduous to go through the generated code, and trying to analyze our own faults while lots of non-treeshakeable dependency code surrounds it just adds to the difficulty.

@arboleya
Copy link
Member

These two issues seem a bit overlapping.

Can we merge them and have a final report to look at?

@arboleya
Copy link
Member

arboleya commented Dec 19, 2023

Also, it'd be good to have a clearer table with everything.

Problematic dependencies

Package KBs (before) KBs (after) Alternative Notes
abc N N xyz Lorem ipsum et dolor..

Problematic packages

Package KBs (before) KBs (after) What needs to be done?
provider N N Lorem ipsum et dolor..

@arboleya arboleya modified the milestones: 1 - Salamander, 2 - Beetle Dec 21, 2023
@FuelLabs FuelLabs locked and limited conversation to collaborators Dec 27, 2023
@nedsalk nedsalk converted this issue into discussion #1592 Dec 27, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
chore Issue is a chore
Projects
None yet
Development

No branches or pull requests

3 participants