Three.js file size when importing via NPM and bundling with Webpack

I’ve installed Three.js via NPM and I’m importing everything as THREE at the top of my script.js file like:

import * as THREE from 'three';

I’m using Webpack to bundle and minify my script.js file (using babel and UglifyJS) and so I believe Three.js is being “tree shook” so that only the used modules (i.e. THREE.Scene) are actually being imported. I’m pretty certain this is happening and no un-used modules are being imported because if I change the line to:

import { Scene, OrthographicCamera, WebGLRenderer, TextureLoader, RepeatWrapping, LinearFilter, ShaderMaterial, PlaneBufferGeometry, Mesh } from 'three';

The file size of bundle.min.js (my final bundled script file) is the exact same as when I do it the first way.

My problem is that when importing THREE, my script.js file jumps from ~133KiB to ~690KiB. I’m importing other library modules (e.g. GSAP) and they are all very small, however importing Three.js jumps the file size up and causes Webpack to give me a warning stating my bundle.min.js is over the recommended file size of 244KiB.

This isn’t the end of the world but ideally, I’d like to make my javascript file as small as possible to improve load times, especially as I’m only using Three.js for a small part of the website.

So basically I have two questions:

  1. Am I importing Three.js correctly for a Webpack setup?
  2. Is there any way to reduce the file size with the imported modules?
1 Like

The treeshakeability of three.js is not ideal at the moment (more information about this topic right here: https://github.com/mrdoob/three.js/pull/14654)

I’m currently working on the first step in order to improve this situation by removing all IIFEs from the codebase and then move towards ES6 classes. When I remember correctly, there is also an open issue in context of three.js's shader library that impedes tree shaking. If those issues are solved, you can expect smaller bundle sizes and a faster startup.

4 Likes

Ah right okay that makes sense, it’s good to know that work is being done on it and like I said it isn’t the end of the world if I have to wait, just would be nice to have it smaller. Thanks for the reply :slight_smile:

@Mugen87 do you have a link to the PR with the shader library? We created some custom solution to get the shaders out of the bundle.

We created a Rollup Plugin which writes every shader into a JSON. On initial page load we send the “shader” json with http-server push to the client and start the three.js scene as soon as the “shader” json arrives. This helped us to improve startup time for mobile devices :tada:

No, sorry. I’ve lately looked after the related discussion at github but I made no find so far.

@Mugen87: with our hacky solution we were able to bring down the size of three.js to 338KB (92.5KB gzipped). And the separate file for the shaders (we call it shaders.json) 96.9 KB (16.7 KB gzipped).

Our experience told us, that a JSON file is much cheaper to parse so we are able to measure a benefit. Especially for mobile devices.

that will be great, and long time waited,
this will enable low size bundles on the web, specially for web 3d viewers,
please let us know on any improvement

Do you have a repo? I’m interested in shaking the heck out of the three-tree, and I’ll help if/when I can.

2 Likes

Sorry, I’ve missed your last post. All IIFEs are now gone but there are some problems in context of ES6 classes. This one is the latest PR: