Best practice webpack + threejs

webpack

#1

Hi - What is the best practice for using webpack with threejs? Adding threejs via modules always throws asset size limit warnings. Is there a proper way to do this or should these warnings be ignored? thx

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

#2

I’d say the best practice is to change your Webpack configuration to increase the size limit of this warning. In my opinion, half a megabyte for such a robust 3D library is a HUGE bargain! However, nobody can tell you what’s an absolute good or bad file size, it’s all relative to what kind of experience you want the user to have.

That being said, chances are that you’re not using every feature of Three.js, so you could import only the classes that you’re using as modules:

First you install Three.js as an NPM module in your terminal or command prompt:
npm install three --save

Then you import individual classes in your JavaScript:
import { WebGLRenderer, Scene, Camera } from "three";

The import above limits the bundle size to those 3 classes, and their dependencies. So it won’t include unused code like TorusBufferGeometry or MeshStandardMaterial.


#3

I think just raising the limit only ignores the underlying problem. The reason why webpack complains about big JS files is the fact that parsing JS is very expensive and cannot be cached or mitigated. For good performance they advocate using less JS (not mainly because of the file size which has to be transfered over the network this can be cached etc but because of parsing). A very interesting blog post about this problem is The Cost Of JavaScript from Addy Osmani. Netflix decided to get rid of React entiryly because the JS affected their performance badly. For more details you can check out their blog post

Now back to the Three.js case. Right now there is no good way to “slice and dice” Three.js to only the parts you need. When you do import { WebGLRenderer, Scene, Camera } from "three"; there will be a lot of other dependencies pulled in because of how Three.js is architectured. Because we also had very strict performance constraints we built or own Three.js build pipe which trims down our Three.js to 88 KB gzip which is about 300KB unzipped. Furthermore, we do not include the Three.js source into our app. So we can load them separately and while the user logs in we can load Three.js.

So back to webpack. I’m not a user of webpack but maybe it’s possible to increase the size limit only for one file? Only for the Three.js bundle? Then you could do the same as we did; one bundle for the app and the app lazyly loads Three.js.

There was an interesting discussion about how to restructure the code base of Three.js to make it better suited for things like tree shaking, you can find details here. But I think right now it’s not really a concern for the core dev team. Maybe we should feedback them that it’s important for some users to have better control of what they want to include when.