Which Components should be wrapped around Suspense?

Hi there,

While I was exploring some Three.js projects on codesandbox I recognized that some objects are wrapped around Suspense while others are living outhside of Suspense.

How to decide which components need to be inside of Suspense?
And what actually is Suspense in simple words?

I know that it takes care of the loading state, but what exctly that means? All objekt inside of Suspense are only loaded when the elements outhside of suspens are already loaded?

So the perspective camera for example should be outhisde of the suspense component right?

Thank you for answers!

1 Like

Anything you like. Even things that have absolutely no relation to Threejs whatsoever.

Suspense is a React component.

React Top-Level API – React (reactjs.org)

That means that everything inside a Supsense component will wait for something before rendering. A Perspective camera dont need to wait for something so it can be outhside a Suspense component, right?

But what about high poly objects, they need to download a lot of data before they can be displayed. Is this also something we concider as “wait for something”? In other words, would you wrap the suspense component around a high poly object?

Use Suspense if you think it adds value to your application.
Good thing about CodeSandBox is that you can delete lines to see what impact they might have.

Suspense is really optional.
For example, I have one demo that has 40 GBs of assets placed around a sphere. I prefer to load them dynamically based on proximity to the camera and not block rendering. But if I wanted all 40 GBs of assets to download across the internet and into my browser before anything was rendered to the canvas, then maybe I could consider using Suspense.

1 Like

I am surprised that it is possible to add 40GB of assets into a scene. Actually I already got some performance issues while I was trying to load a 150MB object into the scene. Do you have a hint for me on how to deal with high poly objects within a three.js scene?

Thank you for your support.

I don’t load all 40GB into the scene, I need to manually manage what’s in the scene when it’s needed. Suspense wouldn’t deliver any magic in my case.
Imagine Google Earth. It doesn’t load all its 550TB into the computers memory before you can use it. It’s managed using something written specific for the purpose.
If you have a very high poly model, then you need to compromise. There is no one answer for everything and you need to experiment.
Begin with some searches related more specifically to the problem you are trying to solve.
You could try using Suspense and then taking it way to see if it actually benefitted your use case.

1 Like

Thank you for your help :slight_smile:

I already changed the model to a low poly object which also looks good…

1 Like

everything you put into the same bound will go live if all async ops have finished. everything out of it is not affected and will render instantly. for instance

<mesh>
  <sphereGeometry />
</mesh>
<Suspense fallback={null}>
  <Model />
  <Environment />
  <ZoomCamera />
</Suspense>

the sphere is sync, it renders immediately. model and environment are async, model most likely uses useGLTF which is suspense, and env loads a RGBE-texture, which is suspense. zoomcamera doesn’t suspend, but it will only render when both the model and the env are finished, all three will render together. so this becomes a formidable way to orchestrate behaviour, for instance, like above, zooming the cam in when everything’s loaded.

you can see an example of that here: Viking ship - CodeSandbox

when do you not want that … in cases where new things come in runtime. for instance, given this:

<Suspense fallback={null}>
  <Model />
  <ModelThatChangesEverySecond />
</Suspense>

when ModelThatChangesEverySecond suspends the fallback is triggered, the fallback is null, that means everything inside the bound unmounts, and mounts again when ModelThatChangesEverySecond is finished. the solution is to wrap it into its own suspense so that it won’t disturb anything else:

<Suspense ...>
  <Model />
  <Suspense ...>
    <ModelThatWillChangeEverySecond />

now Model just remains and ModelThatChangesEverySecond lazily loads and shows when it’s ready.

there are more usecases, read through this to get an idea: https://twitter.com/0xca0a/status/1402558011357470720 in general understanding suspense will boost threejs like nothing else, this solves most if not all loading, async and orchestration problems people suffer from.

ps, i would recommend that you use suspense for each and every asset. suspense isn’t just good for orchestration, it will also allow re-use and memory efficient handling of resources. if you have an async thing and do not put it into suspense, why would you?

2 Likes

@drcmda Wow thats awesome! Highly apprechiate your answer :slight_smile:

I will go through all of this and will make some tests in oder to learn how it will effect my scene.

Thanks a lot!