I have encountered a problem, when loading multiple gltf models at the same time, sometimes the loading fails,but there has no error

this is my code, sometime the loader progress can not to 100% and no error, some time when I clear the browser cache it can be loaded successfully
image

const manager = new THREE.LoadingManager();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("/examples/jsm/libs/draco/");
const gltfLoader = new GLTFLoader(manager);
gltfLoader.setDRACOLoader(dracoLoader);
const modelPaths = [bengzhan1ModelPath, bengzhan2ModelPath, bengzhan3ModelPath, bengzhan4ModelPath, jizhuangxiangModelPath,];

function loadModel(path) {
    return new Promise((resolve, reject) => {
        gltfLoader.load(
            path,
            resolve,
            undefined,
            reject
        );
    });
}

async function initModel() {
    try {
        manager.onProgress = function (item, loaded, total) {
            const progress = Math.floor((loaded / total) * 100);
            console.log(`Loading progress: ${loaded} of ${total} - ${progress}%`);
            $("#loading .Box .pro .pro_back>img").css(
                "left",
                -762 + (loaded / total) * 762 + "px"
            );
            $("#loading .Box .pro .pro_value").text(
                Math.floor((loaded / total) * 100) + "%"
            );
            if (loaded == total) {
                // clearInterval(loading);
                $("#loading .Box .pro .pro_back>img").css("left", -762 + 762 + "px");
                $("#loading .Box .pro .pro_value").text("100%");
                setTimeout(() => {
                    $("#loading").hide();
                    clearInterval(slideTimer);
                    onOff = false;
                }, 1000);
                console.log("=====finished=====");
            }
        };
        await Promise.all(modelPaths.map(path => loadModel(path)))
            .then(results => {
                results.forEach((gltf, index) => {
                    const root = gltf.scene;
                    root.updateMatrixWorld();
                    scene.add(root)
                });
            });

        console.log('All models loaded successfully!');
    } catch (error) {
        console.error(`Error loading models: ${error}`);
    }
}
initModel()

this is a mistake, draco isn’t shipped by three, you need to put the binaries into your /public

other than that, i wouldn’t use timers for anything, all this can do is fail. wouldn’t also want to tie my app status to something as fragile as xhr data. you have async/await, you know exactly where loading starts and ends.

showLoadingUI()
const results = await Promise.all(modelPaths.map(loadModel))
scene.add(...results.map(gltf => gltf.scene))
hideLoadingUI()

It used to be in the js directory, now in jsm/libs…

I think you may just need to include the absolute path

I put draco in this path /examples/jsm/libs/draco/

I put draco in this path /examples/jsm/libs/draco/

I change the load order,one by one to load, in this way, it can be load successfully,I don’t know what happened

const manager = new THREE.LoadingManager();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("/examples/jsm/libs/draco/");
const gltfLoader = new GLTFLoader(manager);
gltfLoader.setDRACOLoader(dracoLoader);
const modelPaths = [bengzhan1ModelPath, bengzhan2ModelPath, bengzhan3ModelPath, bengzhan4ModelPath, jizhuangxiangModelPath,];

function initModel() {
    manager.onStart = function (url, itemsLoaded, itemsTotal) {
        console.log('bengzhan4 Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.');
    };

    manager.onLoad = function () {
        console.log('bengzhan Loading complete!============================');
    };
    manager.onProgress = function (item, loaded, total) {
        const progress = Math.floor((loaded / total) * 100);
        console.log(`Loading progress: ${loaded} of ${total} - ${progress}%`);
        $("#loading .Box .pro .pro_back>img").css(
            "left",
            -762 + (loaded / total) * 762 + "px"
        );
        $("#loading .Box .pro .pro_value").text(
            Math.floor((loaded / total) * 100) + "%"
        );
        if (loaded == total) {
            // clearInterval(loading);
            $("#loading .Box .pro .pro_back>img").css("left", -762 + 762 + "px");
            $("#loading .Box .pro .pro_value").text("100%");
            setTimeout(() => {
                $("#loading").hide();
                clearInterval(slideTimer); 
                onOff = false;
            }, 1000);
            console.log("=====finished=====");
        }
    };
    manager.onError = function (url) {
        console.log('There was an error loading ' + url);
    };
    // model1
    gltfLoader.load(bengzhan1ModelPath,
        (gltf) => {
            console.log('bengzhan1 start');
            const root = gltf.scene;
            root.updateMatrixWorld();
            root.renderOrder = 3;
            loadModel2();
         },
        (xhr) => {
            console.log((xhr.loaded / xhr.total * 100) + '% bengzhan1 loaded');
        },
        (error) => {
            console.log('bengzhan1 An error happened', error);
        }
    );
}

function loadModel2() {
    // model2
    gltfLoader.load(bengzhan2ModelPath,
        (gltf) => {
            console.log('bengzhan2 start ');
            const root = gltf.scene;
            sceneBNDQ.add(root);
            loadModel3();        },
        (xhr) => {
            console.log((xhr.loaded / xhr.total * 100) + '% bengzhan2 loaded');
        },
        (error) => {
            console.log('bengzhan2 An error happened', error);
        }
    );
}
function loadModel3() {
    //same as model2
    loadModel4();
}
...

oh, indeed, that is news to me. though it is useless either way because you can’t fetch from node_modules. maybe three authors weren’t aware of it, but this is basically just extra weight.

that would be also a wrong path. it may work now but it will fail in production. there is a folder for static assets, it is usually called /public. every static asset has to be in there: glb models, binaries, etc. the bundler or build tool will copy its contents into /dist, the output folder. it won’t copy from arbitrary folders and they’ll be missing when you build the site ready for upload.

It’s a nice convenient place to have reference to though, also bodes well for non bundler environments such as the official three examples but yes as you say in a bundled production would ofc fail…

seriously though, packages usually only contain runtime and otherwise declare their dependencies in package.json. it would contribute to slow overall dx and bloat if they didn’t. like if each package would do what three does node_module would weigh terrabytes.

it’s all a bit odd. i’m guessing it’s because the people that dislike tools so much still prefer node & npm to install three, then copy node_modules whole into their projects. and that’s why three needs to carry inlined dependencies. but they all live on npm

npm install draco3d

or cdns.

loader.setDRACOLoader("https://www.gstatic.com/draco/versioned/decoders/1.5.5/")

I don’t think it’s about disliking build tools as such but levels of access to all methods of using the library, in the sense that it can be included into any project from the old way of web development (including the most simplistic usage for beginners) up to the use of node and more complex production builds… i agree on your point that in the three npm package there may be excessive includes but one thing that doesn’t make sense when using npm to install three is that for every directory holding a project, every one of them needs to include it’s own node_modules folder, install of three as well as any other dependencies, so for example 10 seperate projects means 10x installations of three + any other node dependencies, this surely seems like way more bloat than simply downloading three once from source and using import maps to declare where that folder and other dependencies are, being a lot more minimal on storage resources… i guess it’s down to a plethora of factors such as if someone is completely new to programming for the web, what scale of project is being built, if just for fun or for production, what hardware resources are being used, if being included into a modern or old environment, etc. etc. etc. as a highly comprehensive web 3D library (if no the most) three seems to be preserving this inclusive accessibility for good reason…