Bloated js file

Hi I think I may have something configured wrong with webpack and npm when I’m trying to compile my three js file. I’m not really familiar with either of them and new to Three JS as well. Whenever I run npm run build everything works fine but I get this warning;

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
main.js (638 KiB)

WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
main (638 KiB)
main.js

My js is really very small just importing a GLTF model and setting up some lights and using orbit controls and that’s it.

This is what I’m importing:

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

If I comment out these three lines my js is obviously quite small but if I uncomment any one of these lines the file is around 600kb. So whatever I import the file swells. When I look in the compiled main.js file there are lots of embedded console warnings such as:

console.warn("THREE.Ray: .closestPointToPoint() target is now required")
console.warn("THREE.Sphere: .getBoundingBox() target is now required")
console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: "+t)

is npm run build the correct way to compile your project of should I be using a different command when I’m ready to deploy my project?

Any help would be much apreciated as I’m a bit in the dark here. Thanks.

Three.js as a library is over 500Kb, and it’s being bundled together with the rest of your JS. Just because your code is very small, it doesn’t mean that all the required code to display a GLTF model also has to be small.

There have been many attempts at only importing the parts of Three.js that you’re using, but the consensus is that as it’s currently written, the library will always import in full.

There are efforts underway to improve “tree-shakeability” in the future. That being said, the 244Kb recommended size limit is pretty arbitrary, and you can change it in your bundler settings. It would be impossible to do what you’re doing in under 244Kb. Maybe you could try gzipping or minifying your code?

1 Like

Thanks, so would you say 6ookb is ok? It just seemed whatever I imported the file ended up being 600kb even if I didnt import three js and just imported say OrbitControls for instance as a file size test. My code is minified by the compiler BTW but not gzipped.

This is an ongoing issue that we’re working on. In short, it’s because we need to switch to ES6 classes to make tree-shaking work, and we can’t switch to classes until we deprecate certain old files. This will happen in December, so hopefully the build size will go down early next year.

In the meantime, there are workarounds. My favorite is the one outlined by @cream. Note that it’s for Rollup rather than Webpack. But possibly it can be adapted to work with Webpack

If that doesn’t work for you, see my comment further which has a link to @drcmda’s manually trimmed three.js file. instead of importing from the main three.js file, you import from this edited file. However, you have to keep this file updated depending on what parts of the library you use so it’s extra work.

1 Like

600Kb for such a robust 3D library in your browser is a huge bargain, in my opinion! Babylon.js is 2.79MB, and Unity’s WebGL player is even larger.

3 Likes

That webpack-recommended limit is very general — it has no idea whether you’re building a complex PWA, a 3D video game, or a simple static blog. It’s best to understand what limits are reasonable for your application and your users, and set yourself a performance budget accordingly.

Tree-shaking the three.js library is currently quite difficult — we’re working on improving that. But for the moment, I don’t recommend going that route unless you’re really familiar with JS bundling tools.

As others have said here, the bundle size you’re seeing is “normal” (pre-gzip) for a WebGL application. You could reduce it, but not easily. I would make sure you’re using minification and gzip, and then focus on other things. The size of your models and textures can easily become much larger than the JS bundle, so that’s usually a better place to spend your time optimizing.

2 Likes

OK thanks. I’ve had a few problems with my install of webpack recently producing bloated JS (Foundation not Three) and what with the warning I assumed there was a problem with the files size.

Can I just check one final time that if My JS file contains only one line of code (everything else deleted):

import * as THREE from 'three';

and literally nothing else that when I run npm run build and it produces a warning about the 595kib file size that it’s absolutely fine?

Is that ok?

Thanks.

That is the size of the three.js library, yes. If you want to use three.js (and not do a whole lot of work picking apart specific pieces of three.js to use) your pre-gzip size will be what you’re seeing there.

For comparison of WebGL libraries:

1 Like

alright thanks!

i dont think they are right though. any lib over 60kb (gzip) is under no circumstances considered normal in a professional setting. people getting tarred and feathered on twitter all day because bundles exceed a few kb.

lots of artists and agencies avoid threejs due to this (using plain webgl), and to a larger extent i believe this is mostly why webgl struggles to go mainstream.

something like ogl or regl is about 20-40kb, and the only reason threejs can’t be is because it’s rooted in outdated architecture. there’s really no excuse for this, and im very glad this will be addressed. we will see three become much more prevalent after this. :grinning:

I was fairly careful to say normal for a WebGL application — I’m aware of professional web development practices. three.js is used more often than regl or ogl, and I strongly suspect more often than vanilla WebGL (although I don’t have exact stats on that). I don’t think you can argue those choices are more mainstream, or that a new user switching to vanilla WebGL because webpack showed a hardcoded warning is generally a good recommendation.

Also note (more for other readers) that all numbers in this thread so far have been pre-gzip. If you want to compare the 36kb gzipped footprint of regl I would clarify that three.js is 140-150kb gzipped.

three.js also includes helpful things like a scene graph and materials that you don’t have to write from scratch. :wink: It seems unrealistic to expect that enabling tree-shaking will immediately bring three.js down to the smaller footprint of something like regl, but tree-shaking has been discussed in more detail in dozens of other threads at this point.

6 Likes

I’m not arguing that 140-150kb gzipped is the perfect size for a WebGL library — we do spend time working on this stuff. But the question in this thread is about a hardcoded webpack warning, which tree-shaking will not fix, so I think the advice above is correct.

1 Like