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

Build Size grows 5x with ThreeJs 0.150.0 #25595

Closed
rahulp-open opened this issue Mar 2, 2023 · 15 comments · Fixed by #25599
Closed

Build Size grows 5x with ThreeJs 0.150.0 #25595

rahulp-open opened this issue Mar 2, 2023 · 15 comments · Fixed by #25599

Comments

@rahulp-open
Copy link

rahulp-open commented Mar 2, 2023

Description

I installed threejs in a vite project ( vite ^4.0.0).
The threejs version was 0.150.0, the build size was 500kb.
After changing the the three js version to 0.148.0 the build size reduced to 100kb.

There is a huge difference in build size between these threejs versions. Whats causing this issue?

Reproduction steps

  1. Create a vanilla typescript vite project
  2. Install threejs v ^0.150.0 and import it
  3. run vite build
  4. remove threejs v ^0.150.0
  5. Install threejs v ^0.148.0 and import it
  6. run vite build

Check the difference in build size.

Screenshots

three V 0.150.0 Build
high

three V 0.148.0 Build
low

Vite config
viteconfig

Version

0.150.0

Device

Desktop

Browser

Chrome

OS

No response

@rahulp-open
Copy link
Author

@epreston Do you know why the issue is happening?

@epreston
Copy link
Contributor

epreston commented Mar 2, 2023

You are building a library from a library in ES format. The expectation is the final application will do the tree-shaking. It may be as simple as linking cjs in 148 and actual esm in 150.

What's the link to the project ?

@rahulp-open
Copy link
Author

rahulp-open commented Mar 2, 2023

@epreston
image

Im building a ts library with threejs and this is how i'm importing it.
There is no code change between the builds, in both builds the only difference was the change in three js version.
whats causing the difference in build size? is there a way to fix it for v 0.150.0?

@epreston
Copy link
Contributor

epreston commented Mar 2, 2023

Yes. You've got a few issues.

If your project was set up correctly you would expect a maximum of 411 KB for version 148. The maximum for 150 would be 415 KB based on those dependencies.

You're getting something too small for your dependencies to be included on 148 (your 148 is not big enough to contain the required math components) and something too large on 150 for it to be three.js. I need to see what else you have in there.

@epreston
Copy link
Contributor

epreston commented Mar 2, 2023

Link the project, I can run through it.

@marcofugaro
Copy link
Contributor

marcofugaro commented Mar 2, 2023

This is actually a problem on our side, it can be replicated simply with:

import { Scene } from 'three'
export { Scene }

The tree-shaking issue was introduced in #24975, the Object.defineProperties is preventing WebGLRenderer from being tree-shaken when not in use, resulting in the additional 400 kB you see in the bundle.

I have a solution for this, will make a PR shortly.

@epreston
Copy link
Contributor

epreston commented Mar 2, 2023

Yep, that's a "side effect" in a library marked with no side effects in the package.json. Just make it a normal member ?

@LeviPesin
Copy link
Contributor

Just make it a normal member ?

Deprecation warning cannot be logged then.

@epreston
Copy link
Contributor

epreston commented Mar 2, 2023

Quick note: unit tests are not run against this (webglrenderers) on the pull request (as minimal as they are) because it's setup as webonly. This is not my choice. For sanity, you may want to to run the unit tests interactively in web mode to check things.

@rahulp-open
Copy link
Author

@epreston @marcofugaro
https://github.com/rahulp-open/demo-proj

This is a demo project. Here you can see the difference in build sizes when we run "npm run build" for both versions.

@rahulp-open
Copy link
Author

@marcofugaro If you make a PR just tag me.

@marcofugaro
Copy link
Contributor

@rahulp-open I've already made a PR: #25599.
However it needs to be built to be testable.

@epreston
Copy link
Contributor

epreston commented Mar 3, 2023

@rahulp-open that test rig does not include what you are doing in the screenshots above. It simply creates a scene object and logs it to console at the moment. Are you done updating it ?

@epreston
Copy link
Contributor

epreston commented Mar 3, 2023

Using what you have in that demo now, I'm seeing the following:

release r148.0

dist/assets/index-f5119390.js   49.97 kB │ gzip: 14.47 kB

release r150.1

dist/assets/index-a180db9d.js   406.75 kB │ gzip: 103.85 kB

For reference, the project is creating a THREE.Scene object and logging it to the console.

@epreston
Copy link
Contributor

epreston commented Mar 3, 2023

I've updated your project (see rahulp-open/threejs-issue-demo#1) to lock dependencies and build off of source instead of bundles. This allows for consistency between tests and the ability to experiment with the changes referenced above.

Like Marco said above #25595 (comment), you can see how removing the Object.defineProperties( WebGLRenderer.prototype, { block gets the size back down.

release r150.1 (comment out block holding onto WebGLRenderer).

dist/assets/index-d7410eb8.js   59.12 kB │ gzip: 17.89 kB

At the start, that sounds great. The concern I have is it's not useful or practical in isolation. If you think about it for a few minutes, 59 kB for 80 lines of code is still extremely large. If you want to import and export the set of classes in your screenshots, it can be much smaller with different methods. Update the example for your specific use case or link the library project to get more complete feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants