Giter Site home page Giter Site logo

Better tree-shaking about threlte HOT 6 OPEN

Nicell avatar Nicell commented on June 26, 2024
Better tree-shaking

from threlte.

Comments (6)

michealparks avatar michealparks commented on June 26, 2024 1

We recently discussed changing the API for the KTX2Loader in this PR, but your preliminary results has changed my mind a bit. I wonder if it would be potentially a good idea to extract out these loaders into their own hooks (to provide sensible defaults and automatic disposal) and then pipe them into the useGltf hook like so:

import { useDraco, useMeshOpt, useKtx2, useGltf } from '@threlte/extras'

const draco = useDraco()
const meshOpt = useMeshOpt()
const ktx2 = useKtx2()

const gltf = useGltf('/path/to/my.glb', { draco, meshOpt, ktx2 })

This would certainly be tree-shakable. Curious what you think @grischaerbe

The main drawback I can see would be that it would be annoying to configure this if one calls useGltf a lot. This could be solved by a context provider that would be called near the app root:

import { setupGltf } from '@threlte/extras'

// creates a context all useGltf hooks can use
setupGltf({ draco, meshOpt, ktx2 })

Just spitballing ideas, curious if anyone has any better ones!

from threlte.

Nicell avatar Nicell commented on June 26, 2024 1

Thanks Micheal! I was able to use your insights to modify my project to avoid using the T proxy component. Instead, I'm using the T.svelte component directly. It required copying a couple of @threlte/extra component sources into my project for slight modifications, but besides that it's working well!

A Vite plugin to do what you describe would be a much better solution, but I don't have the expertise or time to make something like that at the moment.

The end result is a reduction of 18% (180kb) in my bundle size by avoiding the wildcard import and a 7% (70kb) reduction by avoiding the GLTF loaders I'm not using. Overall a 25% reduction in my bundle size!

It would be great to see these tree-shaking wins built into Threlte with an updated useGltf API and bundler plugins to remove the wildcard import.

from threlte.

DefinitelyMaybe avatar DefinitelyMaybe commented on June 26, 2024

interesting, looking forward to your investigation

from threlte.

Nicell avatar Nicell commented on June 26, 2024

If I had to guess on the three.module.js increase in size, I would say it's because the @threlte/preprocess package was dropped. It looks like it helped with tree shaking three.module.js, and in the newer versions of Threlte, import * as THREE is used, which defeats the purpose of three.module.js's tree-shaking capability from my understanding.

To give exact numbers, on the same three.js version (150) and upgrading from Threlte 5 to 7, I'm seeing the size of three.module.js increase from 850kb to 1,120kb. That amount increase likely depends on the application, but that's a fairly significant increase IMO, and I'd love to be able to get this back down. If it would be helpful, I could spend some time creating a tiny vite project on both 5 and 7 to see the difference in bundle size as a minimum reproduction.

from threlte.

michealparks avatar michealparks commented on June 26, 2024

In @threlte/core the THREE wildcard import is used in one place: the <T> component, specifically to resolve Three.js imports for the <T.[SomeThreeClass]> syntax. Since there isn't any determinism here I think it would be impossible to remove without a compile step, but I wonder if some kind of Threlte tree shaking vite plugin for production builds could be made that does this...

  1. converts all files like this:
<script>
  import { T } from '@threlte/core'
</script>

<T.Mesh>...</T.Mesh>

into this:

<script>
  import { Mesh } from 'three'
  import { T } from '@threlte/core'
</script>

<!-- A completely legit alternate T syntax -->
<T is={Mesh}>...</T>
  1. Before bundling replaces the internal <T> component with a simpler one that does not support the dot syntax and therefore has no wildcard import

There may be edge cases since I'm thinking of this off the top of my head, but it would probably solve the issue you're describing.

from threlte.

michealparks avatar michealparks commented on June 26, 2024

@Nicell I've created an experimental vite plugin to automate tree shaking here: https://github.com/michealparks/threlte-minify

I've been using it in a few projects for a few weeks now with good results. If you end up using Svelte 5 soon and are interested in testing it out as well then I'd appreciate it! If desire / traction picks up for this then I'll eventually ship it to NPM.

from threlte.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.