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

refactor: optimize bundle size with isolated modules #1839

Merged
merged 47 commits into from
Dec 13, 2023

Conversation

anuraghazra
Copy link
Member

@anuraghazra anuraghazra commented Nov 23, 2023

The problem:

Currently blade is bundled into a single index.js file and gets shipped to consumers, which consumers then import and treeshake.

This works for treeshaking the whole bundle as a single module but this creates an issue where lazy loading components / codesplitting components doesn't work, if consumer tries to codesplit a component from blade it will always remain in the main bundle instead of in a new chunk.

react-router also has the similar problem, read more here.

The Solution:

Instead of bundling into a single index.js file, this PR changes the bundled output to preserve the original file structure via rollup's preserveModules flag and separate each module on it's own file. This way webpack will be able to individually codesplit/treeshake modules.

The bundled output now looks like this:

  • build
    • lib
      • web
        • production
          • components
          • tokens
          • utils
        • development
          • components
          • tokens
          • utils
      • native
        • components
        • tokens
        • utils
    • types
      • components/ (index.d.ts | index.native.d.ts)
      • tokens/ (index.d.ts | index.native.d.ts)
      • utils/ (index.d.ts | index.native.d.ts)

Further Bundle Optimizations

  1. Lodash But Better

We've removed lodash as a dependency from blade and instead use alternative lightweight version of the utilities that we use internally.

  1. Marked component specific dependencies as optional peerDependencies

Previously we used to bundle dependencies like @use-gesture/react, tinycolor2 with blade, which means even if you are not using BottomSheet or createTheme you'll get the bundle of these libraries.

  1. Code split optimisation

And finally, with this change consumers can now properly do lazy loading of components and webpack will be able to create chunks.

  1. Mark blade as sideEffects: false

Another problem which occurred because of Table, since Table uses @react-table/table-library & @emotion/react, emotion is causing side effects and both of these libraries gets included in the bundle, to fix these issues we marked blade as sideEffects:false in package.json.

Unfortunately, there is still an issue with emotion which causes around 5kb of bundle to still get into the main bundle even with sideEffects:false. This we can explore later on how to solve.

Impact:

After rendering a vite app with 1 button:
Before (v10.19.1): 104kb gzip
After: 78kb gzip
Reduction: 26kb

emotion-js/emotion#1279

Copy link

changeset-bot bot commented Nov 23, 2023

🦋 Changeset detected

Latest commit: 07deaa3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@razorpay/blade Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@anuraghazra anuraghazra changed the base branch from rip-lodash to master November 23, 2023 08:15
@anuraghazra anuraghazra changed the base branch from master to rip-lodash November 23, 2023 08:15
Copy link
Contributor

github-actions bot commented Nov 23, 2023

✅ PR title follows Conventional Commits specification.

@anuraghazra anuraghazra changed the base branch from rip-lodash to rollup-pls November 23, 2023 08:16
Copy link

codesandbox-ci bot commented Nov 24, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 07deaa3:

Sandbox Source
razorpay/blade: basic Configuration

Copy link
Member

@saurabhdaware saurabhdaware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check carousel story once? seems like its broken.
https://61c19ee8d3d282003ac1d81c-tenvvkemkx.chromatic.com/?path=/story/components-carousel--default-carousel

Might have to take a look at components that are using a bit complex lodash methods. I'll try testing few from my end

@anuraghazra
Copy link
Member Author

Can you check carousel story once? seems like its broken.

Checked. Imports were breaking.

@anuraghazra anuraghazra added Review - L2 Second level of review and removed Review - L1 First level of review labels Dec 11, 2023
Copy link

bundlemon bot commented Dec 11, 2023

BundleMon

Files removed (6)
Status Path Size Limits
Web Components
build/components/index.production.web.js
-330.06KB -
React Native Components
build/components/index.native.js
-187.05KB -
Web Tokens
build/tokens/index.production.web.js
-42.24KB -
React Native Tokens
build/tokens/index.native.js
-38.35KB -
Web Utils
build/utils/index.production.web.js
-3.38KB -
React Native Utils
build/utils/index.native.js
-2.27KB -
Unchanged files (8)
Status Path Size Limits
CSS Theme Tokens
build/css/paymentThemeDarkDesktop.css
4.55KB -
CSS Theme Tokens
build/css/paymentThemeDarkMobile.css
4.54KB -
CSS Theme Tokens
build/css/bankingThemeLightDesktop.css
4.53KB -
CSS Theme Tokens
build/css/bankingThemeLightMobile.css
4.52KB -
CSS Theme Tokens
build/css/bankingThemeDarkDesktop.css
4.52KB -
CSS Theme Tokens
build/css/paymentThemeLightDesktop.css
4.52KB -
CSS Theme Tokens
build/css/bankingThemeDarkMobile.css
4.51KB -
CSS Theme Tokens
build/css/paymentThemeLightMobile.css
4.51KB -

Total files change -603.34KB -94.34%

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

packages/blade/package.json Outdated Show resolved Hide resolved
# This script is used to build the blade package.
set -e

yarn build:clean
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also use it without glob pattern like run-s build:clean build:generate-types build:react-prod build:react-dev build:react-native, right?

yarn add @razorpay/blade [email protected] @floating-ui/react
yarn add @razorpay/blade [email protected]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@floating-ui/react is no longer a peer dependency?

@kamleshchandnani kamleshchandnani merged commit 40e51a5 into master Dec 13, 2023
14 checks passed
@kamleshchandnani kamleshchandnani deleted the anu/bundle-optimize-wip branch December 13, 2023 12:27
anuraghazra added a commit that referenced this pull request Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review - L2 Second level of review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants