felixmariotto / three-mesh-ui

⏹ Make VR user interfaces for Three.js
https://felixmariotto.github.io/three-mesh-ui/#basic_setup
MIT License
1.31k stars 138 forks source link

refactoring #13

Closed felixmariotto closed 4 years ago

felixmariotto commented 4 years ago

OK, so we talked about a lot of possibilities, I would like to sum things up and organise to draw a practical roadmap.

These are points to work on, roughly in order :

1) As outlined in #12, three-mesh-ui needs a bit of refactoring, for a better separation of concerns.

2) As outlined in #3, three-mesh-ui components should inherit from THREE.Object3D, for a more convenient raycasting and transforming of the root component.

3) The refactoring should help with the bug you mentioned in #7, since we will have a module that will position glyphs in a container, whatever their type (SDF, geometry, vector, etc..). It should also provide a standard object to raycast to, whatever the text type, as requested in #1

4) As outlined in #11, it needs new text classes, including InstancedText, VectorText, and CanvasText. One of the classes must be aliased to Text, which should be the most versatile, a good default for beginners.

5) As outlined in #9 and #5, it needs some updates related to bundling, in order to:

@trusktr as you seem interested in the project, do you want to collaborate with some of these points ? If so which ones ?

I'm planning on dropping what I was doing with InstancedMesh for the moment, which was mostly getting nowhere. In my opinion the first two points should be addressed first, as it is the foundation for everything else.

Edit -- Some addition :

trusktr commented 4 years ago

About point 2, I'm not so sure yet. I need to learn more first...

do you want to collaborate with some of these points ? If so which ones ?

I often post more ideas than I can handle at once. xD I'll have more of an idea what I can contribute to first once I understand the code more. As far as currently, point number 5 most likely requires the least amount of knowledge of how the code works, so maybe I can start with that in order to get more familiar.

felixmariotto commented 4 years ago

No problem, your giving so much feedback is in itself a great thing for the lib. So feel free to address point number 5 when you can then, I will go ahead with the first two.

felixmariotto commented 4 years ago

I think it would be really cool to create an index to "hard-tree-shake" like this : https://github.com/drcmda/testlighting/blob/faed149a35d44d116b5c30434f26fb3f98b0d07b/src/utils/three.js

I've seen it explained here : https://discourse.threejs.org/t/how-to-reduce-bundle-size-with-webpack/14607/5?u=felixmariotto

I think it could reduce the bundle size bellow 100kb, it would be a great leap forward.

The lib only needs those three.js modules :

The examples however need basically the whole three.js (webGLRenderer.. etc.. ), so when bundling the examples, the whole three.js should be injected.

trusktr commented 4 years ago

What I do is import from files directly when I want hand-rolled guaranteed tree shaking. For example, instead of

import {Foo} from 'three' // side-effect of importing everything

I write

import {Foo} from 'three/path/to/Foo'

Then no matter which bundler I use, or even the code is being imported with native ES Modules, then I know at least it imports only the specific modules.

The was the ES Module spec works is, technically, if you import an index file it must import everything so that it can guarantee all intended side-effects are intact.

Technically in that regard the tree shaking that some bundlers do is not to spec. So the best way (closest to spec) is to import from specific modules to get exactly what you want.

felixmariotto commented 4 years ago

Mh yes this looks like the cleanest solution and it's quick, I will try that tomorrow. Thanks for the heads up πŸ‘Œ

felixmariotto commented 4 years ago

@trusktr I've tried both import {Foo} from 'three/path/to/Foo' and import {Foo} from 'three/path/to/Foo.js', but it doesn't tree-shake at all, it actually made the bundle a little bit more fat. I guess that's because of my webpack config, how is your own config ?

trusktr commented 4 years ago

Wow, you've been HACKING!! I like the new examples.

it actually made the bundle a little bit more fat

Hmmm... importing from those files directly and never the entry point should make things slimmer than importing from the entry point.

I am planning to circle back around and will start to dig in.

felixmariotto commented 4 years ago

Thanks !

Yeah this tree-shaking problem is annoying... Now the bundled lib is 812kb, whereas there is only maybe 15kb of three-mesh-ui inside. If people are importing three and three-mesh-ui via script tags, it's a major waste.

trusktr commented 4 years ago

If people are importing three and three-mesh-ui via script tags, it's a major waste.

They definitely should not be doing that. If they are using import they should be keen enough not to rely on globals. If they have the correct version of Three.js as a dependency for their app, so it is in-range with the one from three-mesh-ui, and they are using import, then they should not have extra baggage.

It may not be for everyone, but I think at least for experience web devs including a script tag is not the best way to go (for reasons that it includes everything).

This problem isn't limited to three-mesh-ui. It is a problem with any library.

Maybe what could help is a starter repo for three-mesh-ui with everything set up the best way.

felixmariotto commented 4 years ago

Yes a starter repo could help.

Anyway it's not a very urgent problem. Although giving an option for script tag import is important for accessibility (beginners in web development should be able to use it too), it's unlikely that this type of users bother a lot about the bundle being 815kb instead of 15kb.

trusktr commented 4 years ago

giving an option for script tag import is important for accessibility

Totally! I agree, having both options is good. Most important is for someone to build something without hassle, then they can optimize later, if needed.

felixmariotto commented 4 years ago

Most important is for someone to build something without hassle, then they can optimize later, if needed.

Yes for instance, also a lot of people start programming or web development with three.js... And when you start learning web development, bundling is an added complexity to the already steep learning curve, so it's tempting to use script tags for a while before to use the "new" NPM-ES6-bundler ecosystem. I can tell because it's only been two years I use JS, I started with three.js, and I learned how to bundle only a few months ago.

Just yesterday I had someone having trouble using the lib with script tags. Turns out I messed up my webpack config, which I fixed... My point is, giving the script tags option is a very needed feature.

trusktr commented 4 years ago

Yeah. Let's help newbs have a good time. πŸ‘πŸ˜ƒ

By the way! Are you in the new Three.js Discord server? https://discord.gg/cjcPJHH