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

NextJS 13 unused client component increases First Load JS size (tree shaking not working for client component) #49742

Open
1 task done
TrustyTechSG opened this issue May 13, 2023 · 9 comments
Labels
area: app App directory (appDir: true) bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@TrustyTechSG
Copy link

TrustyTechSG commented May 13, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.15.0
      npm: 9.5.0
      Yarn: 1.22.19
      pnpm: N/A
    Relevant packages:
      next: 13.4.2
      eslint-config-next: 13.3.0
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 4.9.5

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true)

Link to the code that reproduces this issue

https://github.com/TrustyTechSG/tree-shaking

To Reproduce

File structure as below:
app/components/ComponenA.js
app/components/ComponentB.js (is client component "use client")
app/components/index.js
app/page.js
app/layout.js

components/index.js re-export ComponentA and ComponentB.

export * from "./ComponentA";
export * from "./ComponentB";

Only use componentA in page.js
import { ComponentA } from "./components";

Describe the Bug

ComponentB is not used, but it still increases First load JS size.

Before add ComponentB
image

After add export * from "./ComponentB" to app/components/index.js
image

Expected Behavior

Tree shaking ComponentB, it should not effect the First load JS size.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

NEXT-1799

@TrustyTechSG TrustyTechSG added the bug Issue was opened via the bug report template. label May 13, 2023
@github-actions github-actions bot added the area: app App directory (appDir: true) label May 13, 2023
@roch-numbered
Copy link

I've been digging into a similar issue and it seems that on your example, adding modularizeImports option into next.config.js solves the issue.

const nextConfig = {
	modularizeImports: {
		'./components': {
			transform: './components/{{member}}',
			skipDefaultConversion: true,
		}
	}
}

I uncommented the export in src/app/components/index.js and ran build task and the 'First Load JS' is 82.7 kB.

@TrustyTechSG
Copy link
Author

I've been digging into a similar issue and it seems that on your example, adding modularizeImports option into next.config.js solves the issue.

const nextConfig = {
	modularizeImports: {
		'./components': {
			transform: './components/{{member}}',
			skipDefaultConversion: true,
		}
	}
}

I uncommented the export in src/app/components/index.js and ran build task and the 'First Load JS' is 82.7 kB.

Hi @roch-numbered , thank you for the solution. Yes, in fact, I have 50 lines of modularizeImports for now to walk around this issue and also as 13.1 suggested to improve the fast reload speed, but just thought the tree shaking should be default without the need of using modularizeImports.

@SaveliiLukash
Copy link

To be honest, was also expecting tree shaking to work out of the box. Good to have a way to configure it, but still...

@Antonio-Laguna
Copy link

This seems to be now superseded by optimizePackageImports, however, I couldn't get this to work with an internal library. As soon as use client is used it just includes it and increases the payload.

@ivan-kleshnin
Copy link
Contributor

ivan-kleshnin commented Nov 14, 2023

however, I couldn't get this to work with an internal library.

From the docs, it sounds like it's not even supposed to...

We're being fed with self-praising posts about huge bundle size reductions but the reality is that app router + Turbopack bundles are larger than pages router + Webpack ever were. Because of issues like this.

The regression with barrel files happened in version 13, a year ago!
It's even marked as a "Good First Issue"... No reply from the Next.js core team ever since.

@shuding
Copy link
Member

shuding commented Dec 5, 2023

@Antonio-Laguna is there for fixing the bug: #59254. However, it's generally better to not put "use client" directly inside the barrel file. Instead, it should be put on top of each exported component if they're Client Components.

@shuding shuding added the linear: next Confirmed issue that is tracked by the Next.js team. label Dec 5, 2023
@Antonio-Laguna
Copy link

@shuding I wasn't using "use client" in a barrel export but rather in the appropriate file so tree-shaking can do its thing. Though I don't use barrels in normal projects, I can't find great ergonomics for libraries. Are you implying this is because of a barrel structure?

@shuding
Copy link
Member

shuding commented Dec 5, 2023

Also it's necessary to note here that this bug is very different (and not related to) our bundling improvements of barrel and other optimizations. The bug here is specifically related to client boundaries ("use client"), so this is incorrect as RSC isn't supported in pages:

that app router + Turbopack bundles are larger than pages router + Webpack ever were.

@shuding
Copy link
Member

shuding commented Dec 5, 2023

@Antonio-Laguna Thanks for the quick reply! I see, it sounds like then it's not related to optimizePackageImports then.

We'll prioritize this issue in the meantime 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: app App directory (appDir: true) bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

No branches or pull requests

6 participants