-
Notifications
You must be signed in to change notification settings - Fork 28.2k
Tree-shaking/Code splitting doesn't with react-aria-components #60246
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
Comments
@samcx any news about this? |
@IonelLupu I haven't been able to yet! Will let you know when I dig into this |
@samcx I can help with this. Let me know some quick steps to begin with: where to look (folders, files). It might be something with the webpack terser where it doesn't remove the dead code from node_module files. But not sure |
@IonelLupu Thanks for assisting! I was able to replicate the large bundles with your Even tried using optimizePackageImports to no success. We may have an issue with our Server Component bundling. We'll be taking a deeper look at this! |
@samcx let me know if I can help with a PR.
Based on its name ('Server Component bundling'), it seems that resolving this will only address the bundle size for server components. Is there a "Client Component bundling" that needs to be fixed too? Because that has issues as well. It's also explained in the issue above here (although, in not a great way as it lacks some words. Sorry 😅 ), but I also explained it here: adobe/react-spectrum#5639. Long story short: if you use, for example, a Button on page A (let's say 10kb in size) and then a Table and DatePicker on page B (let's say these have a total of 80kb), you would expect the difference in bundle size between page A and page B to be around 70kb, right? In reality, it's not like that. Now, both page A and page B now have a bundle size of 90kb: the combined value. Not sure if this is also a NextJS issue or a react-aria-components issue |
@IonelLupu Apologies for the late response! We're still taking a look at this. We can confirm that there is an issue with bundling when you import a Client Component (from the other thread, I see that the Will circle back when we have more updates on this. |
FYI, we decided to remove "use client" from |
@devongovett Thank you for the clarification! |
thank you @devongovett . We were able to shave almost 20% of bundle size. 🥳 One caveat though: we also use buttons inside |
@federicocappellotto97 did you use the latest version of react-aria-components. They kinda fix the problem |
Yes, we're using: |
We're cooking an optimization solution (PR #62238) for the cases like react-aria-components import, after this being landed nextjs will be able to do tree-shaking optimization to the direct imports from client components, if there's no shared component as barrel file in between. Sharing some testing result: If we compare the After
Before
|
…onent module (#62238) ### What & Why This PR helps fixes a long time tree-shaking issue that if you're import some identifiers from client components, the whole client component is being included in the client chunk. Because we're using import eager mode in webpack to include all the client component modules that make sure they're present in SSR entry and browser entry when they're transformed to client reference on RSC layer. But the way we collect client components is a bit "aggressive" where contains some spaces to optimize. ### How We change the collected client components from simpliy collecting it resolved module request, into collecting both the imported identifiers (by server components) and the module request. And when we inserted the used client components imports into the SSR and Client entry, leverage webpack magic comments `"webpackExports"` to only contain the used exports in the bundle. Thank you webpack for this nice feature : ) Along the way we also fixed an issue that when you only used default export, the `default` export itself should also be proxied when the bundle is in ESM. #### Notice There's a limitation yet that it can't work with barrel file, if you have a shared component `index.js` to re-export the changes several client components there and you only partially import few from `index.js` it won't work. For the cases that the node_modules package contain a barrel file importing multiple client components, please use [optimizePackageImports](https://nextjs.org/docs/app/api-reference/next-config-js/optimizePackageImports) config for now. We'll have follow up optimizations ### Testing Result If we compare the `react-aria-components` the reproduction from #60246, you'll see the result being optimized a lot: #### After vs Before 134KB being tree-shaked out 🤯 ``` Route (app) Size First Load JS ┌ ○ / 324 B 127 kB ├ ○ /_not-found 872 B 86.5 kB └ ○ /other-page 174 B 127 kB ``` ``` Route (app) Size First Load JS ┌ ○ / 325 B 261 kB ├ ○ /_not-found 870 B 86.5 kB └ ○ /other-page 176 B 261 kB ``` Fixes #60246 Related report: adobe/react-spectrum#5639 Closes NEXT-2527 phase 1 of NEXT-1799 --------- Co-authored-by: Shu Ding <g@shud.in>
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Discussed in #60206
Originally posted by IonelLupu January 4, 2024
Summary
We started to use react-aria-components in our NextJS project and we encountered something strange: when using just a simple
<Button>
from react-aria-components, the entire 140kb+ react-aria-components package is imported in the app as seen in the next-bundle-analyzer report below:At first, I thought this is a problem with how the files are exported from react-aria-components.
I don't think this is the case, because a Vite React project shows it only imports under 40kb of react-aria-components packages as seen in the vite-bundle-visualizer report below:
Is next-bundle-analyzer outputting wrong data or is there a problem with the NextJS builder?
Following this issue, I came across other two opened issues:
'use client'
directive required for unused transpiled components. #44039Reading these I noticed that using 'use client' in every page does bring the react-aria-components package size down to ~40kb:

You might thing the issue is solved, but nooo.
As you will notice in the NextJS repos I created to replicate the issue and I listed below, the "/" page is using a simple
<Button>
and the "/other-page" is using a more complex<Select>
component. Still, the "/" page that is using only a<Button>
contains all of the modules for the<Select>
component EVEN IF the "/" page is not using the<Select>
component at all. 🤯Here is another example where I have a page with a

<Table>
from react-aria-components (I didn't add this page in the repo, but you get the idea). The bundle size goes crazy to around ~140kb:In order to see this yourself, clone the NextJS repo linked below. From there, check these scenarios:
Scenario 1: run

npm run build
. In the "client" bundle analyzer browser tab, after you select the "app/page" file, you will see the bundle have around 36kb. This contains both the Button and Select modules:Scenario 2: delete the entire "other-page" folder and run
npm run build
again. In the "client" bundle analyzer opened tab, after you select the "app/page" file. Notice the bundle size for react-aria going down to around ~15kb. It contains only the modules for . Below are some screenshots for both the "app/page" page and "app/other-page/page" page:Scenario 3: remove the 'use client' from the "app/page.tsx" file and run

npm run build
again. In the "client" bundle analyzer opened tab, after you select the "app/page" file. Notice the bundle size going up to ~140kb for react-aria. It contains the ENTIRE "react-aria-components" libraryUsing

modularizeImports
doesn't work for react-aria-components, but I think this is a react-aria-components issue:Also, using
"sideEffect": false
doesn't do anything either.I don't know what happens, but it seems NextJS is summing up all the used imports and uses that FOR EVERY SINGLE PAGE that uses react-aria-components.
It should split the react-aria-component library based on every component used for that particular page.
Here are the repos you can use to see the difference:
Additional information
Example
https://github.com/IonelLupu/react-aria-button-bundle-size-nextjs
The text was updated successfully, but these errors were encountered: