⚡️ Limited Black Friday Deal
Get 50% off on the React Three Fiber Ultimate Course with the promo code ULTIMATE50
Buy Now
Fundamentals
Core
Master
Shaders
Loading Screen
In 3D experiences, it is common to have complex models and large textures. This can lead to long loading times. To avoid having a blank screen and bad first impressions, we can add a loading screen.
I personally think that when possible, a loading screen should be avoided (Unless it's a design choice). Optimizing models and textures should be considered first.
But sometimes you have no choice, and even optimized models can stay large or you have many of them. In this case, a loading screen can be a good solution.
Suspense
Suspense is a React wrapper component that allows you to render a fallback component while waiting for data to load.
That data in traditional apps refers usually to data fetching or code splitting. But in React Three Fiber, we can use it to wait for models and textures to load.
useLoader
hook uses promises to load models and textures. So we can use Suspense
to wait for them to resolve.
In the starter pack I have added 4 models in public/models/
of +3MB each. (Which is a lot for a web app as they all contains the same animations and could/should be optimized) That will allow us to see how Suspense
works.
When I reload, we have a long blank screen before the models are loaded. This is not a good user experience, users could think that the app is broken and leave.
I you are working locally or have the models cached in your browser, you might not see the blank screen.
To force reloading the resources, you can disable the cache in the Network tab of your browser dev tools.
You can also slow down the network with the Throttling option.
Now we all should see the blank screen, let's add a Suspense
component with a fallback
prop:
import { Canvas } from "@react-three/fiber"; import { Experience } from "./components/Experience"; import { Suspense } from "react"; const CubeLoader = () => { return ( <mesh> <boxGeometry /> <meshNormalMaterial /> </mesh> ); }; function App() { return ( <> <Canvas camera={{ position: [-4, 4, 12], fov: 30 }}> <Suspense fallback={<CubeLoader />}> <group position-y={-1}> <Experience /> </group> </Suspense> </Canvas> </> ); } export default App;
Our fallback
component is a simple cube, it is not the best looking loading screen, but it is enough to understand how Suspense
works.
When we reload, we can see that the cube is displayed while the models are loading. When they are loaded, the cube is replaced by the Experience
component.
Preload
A common issue you can face is that your resources are not required immediately. For example, you can have a model that is loaded only when the user clicks on a button. So it won't be taken into account by Suspense
.
That can lead the fallback
component to be displayed again when the resource is required. To avoid that, we can use the preload
function from the different Drei loaders.
End of lesson preview
To get access to the entire lesson, you need to purchase the course.