Use the useGLTF to load async

useGLTF take the main thread while loading , and this modalviewer is one of the component is in main component so while loading the other actions like small animation not work untill load is complete

import { Canvas  } from '@react-three/fiber/native';
import { Suspense } from 'react';
import { View, ActivityIndicator} from 'react-native';
import { OrbitControls, useGLTF ,Bounds , useBounds,Grid } from '@react-three/drei/native'; // Ensure to use native version
import React , {useEffect , useState , memo} from 'react';
// import img from '../assets/images/legt1.glb'
import colors from '../styles/colorTheme';


const Trigger = ({ setLoading }) => {
    useEffect(() => {
        setLoading(true);
        return () => {
        setLoading(false);
        };
    }, [setLoading]);

    return <></>;
};

// Fallback loader component
const Loader = () =>{

    
    return (
        <View style={{position : "absolute" ,top : 0 , left : 0 , right : 0 , bottom :0 ,justifyContent : "center" , alignItems : 'center'}}>
            <ActivityIndicator size="large" color={colors.primary} />
        </View>
    );
}

const Model = ({ path })=> {
    
    const {nodes, scene } = useGLTF(path); 
    const model_api = useBounds();
    useEffect(() => {
        if (scene) {
          console.log('3d model is now rendering..');
          model_api.refresh(scene).fit();
        }

        return ()=>{
            console.log("ummounting happeing");
            useGLTF.clear(path)
            console.log("unmounting has done");
            
        }
      }, []);

    const customDisposeLogic = (object)=> {
    
        if (object.geometry) object.geometry.dispose();
        if (object.material) object.material.dispose();
    }

    return (
        <group>
            {Object.entries(nodes).map(([name, node]) =>
                node.isMesh ? (
                <mesh
                    key={name}
                    geometry={node.geometry}
                    position={node.position}
                    name={name}
                    castShadow ={false}
                    material={node.material}
                    dispose={customDisposeLogic}
                />
                    
                ) : null
            )}
        </group>
    )
}
function ModelViewer({source = null}) {

    const [loading, setLoading] = useState(false);
    useEffect(()=>{
        console.log("it is rendering ");
        
    })
    return (
        <View style={{height:"100%" , width:"100%" , position :"relative"}}>

            {loading && <Loader />}
            {source && 
            
                <Canvas >
                    <Suspense fallback={<Trigger setLoading={setLoading} />}>

                        <ambientLight intensity={1} />
                        

                            <Bounds>
                                <Model path={source} />
                            </Bounds>

                        <Grid position={[-1, 0,-1]} cellSize={.2} cellThickness={1} fadeDistance={10} fadeFrom={10} infiniteGrid sectionColor={"gray"} cellColor={"gray"}  rotation={[Math.PI / 2, 0, 0]}/>

                        <OrbitControls 
                            makeDefault 
                            minPolarAngle={0} 
                            maxPolarAngle={Math.PI / 1} 
                        />
                    </Suspense>

                </Canvas>
            
            
            }
        </View>

    );
}

export default memo(ModelViewer);


so how to resolve this issue

loading doesn’t happen in the main thread, it is async. once threejs starts parsing the data then its in the main thread. there is nothing you can do about that except throwing threejs into a worker: GitHub - pmndrs/react-three-offscreen: 📺 Offscreen worker canvas for react-three-fiber

here’s a demo https://offscreen.pmnd.rs/ no matter how hard it loads or performs, it will never disturb the dom.

btw you don’t need to have so much code around the loader. you can either put the suspense outside canvas, then you can render a dom component. or use GitHub - pmndrs/tunnel-rat: 🐀 Non gratum anus rodentum

I am using this in react native and after the loading become true, other button action will not execute until the loading of 3d modal is complete, once loading complete all the action related to previous pressing of button happens