Load GLTF Models Asynchronously in Three.js

This article provides a step-by-step guide on how to asynchronously load external 3D models into a Three.js scene using the GLTFLoader. You will learn how to set up the loader, handle asynchronous loading using callbacks, and implement modern async/await patterns with Promises to manage your 3D assets efficiently.


1. Import Three.js and GLTFLoader

Before loading a model, you must import the core Three.js library and the GLTFLoader extension. Since GLTFLoader is an addon, it must be imported separately.

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

2. Asynchronous Loading Using Callbacks

The default way to load a GLTF model asynchronously in Three.js is by using the .load() method of the GLTFLoader. This method takes four arguments: the file URL, a success callback, a progress callback, and an error callback.

Because the file is loaded over the network, this process is non-blocking. The rest of your JavaScript code will continue to run while the model downloads in the background.

// Initialize the loader
const loader = new GLTFLoader();

// Load the 3D model asynchronously
loader.load(
    'path/to/model.gltf', // URL of the model
    function (gltf) {
        // Success callback: Executed once the model is loaded
        const model = gltf.scene;
        scene.add(model);
        console.log('Model loaded successfully!');
    },
    function (xhr) {
        // Progress callback: Executed during the loading process
        console.log((xhr.loaded / xhr.total * 100) + '% loaded');
    },
    function (error) {
        // Error callback: Executed if something goes wrong
        console.error('An error occurred while loading the model:', error);
    }
);

3. Asynchronous Loading Using Async/Await

To write cleaner, more readable synchronous-looking code, you can wrap the GLTFLoader in a Promise. This allows you to use async and await structures, which is ideal when you need to load multiple assets before initializing your scene.

Step A: Create a Promisified Loader Function

const loadGLTF = (url) => {
    return new Promise((resolve, reject) => {
        const loader = new GLTFLoader();
        loader.load(
            url,
            (gltf) => resolve(gltf),
            undefined, // Progress callback omitted for simplicity
            (error) => reject(error)
        );
    });
};

Step B: Load the Model with Async/Await

You can now call this function inside an async block, using try...catch to handle loading errors.

```async function initScene() { try { // Wait for the model to finish loading without blocking the main thread const gltf = await loadGLTF(‘path/to/model.gltf’);

    // Add the loaded model to your scene
    scene.add(gltf.scene);
    
    // Start the animation loop after the asset is ready
    animate();
} catch (error) {
    console.error('Failed to load the 3D model:', error);
}

}

initScene(); ```

Using either of these asynchronous patterns ensures that your Three.js application remains responsive, preventing the browser window from freezing while large 3D models are downloaded and parsed.