Javascript 如何提高Gatsby.js/react中three.js场景的性能?

Javascript 如何提高Gatsby.js/react中three.js场景的性能?,javascript,reactjs,three.js,gatsby,Javascript,Reactjs,Three.js,Gatsby,我在useffecthook中渲染了一个相对简单的three.js场景。它使用GLTFLoader()加载模型 页面上还有三个在加载时激发的事件侦听器。一个是计算浏览器的内部高度,另一个是跟踪用户何时调整浏览器的大小(以调整three.js场景的大小),最后一个是为three.js模型执行简单的鼠标视差效果 当前我面临的问题是页面加载时的fps低/口吃,但一旦加载,场景的交互性就会平滑/60fps。 我在这里怀疑的是,我的代码在渲染时一次发生了太多事情,这也是我在网上询问专业人士的原因。有人建议

我在
useffect
hook中渲染了一个相对简单的three.js场景。它使用
GLTFLoader()
加载模型

页面上还有三个在加载时激发的事件侦听器。一个是计算浏览器的内部高度,另一个是跟踪用户何时调整浏览器的大小(以调整three.js场景的大小),最后一个是为three.js模型执行简单的鼠标视差效果

当前我面临的问题是页面加载时的fps低/口吃,但一旦加载,场景的交互性就会平滑/60fps。

我在这里怀疑的是,我的代码在渲染时一次发生了太多事情,这也是我在网上询问专业人士的原因。有人建议我先预加载模型,然后再进行渲染,但我不知道如何在gatbsy.js中做到这一点

这是代码。正如我前面提到的,在react呈现页面之后,整个three.js场景在useEffect钩子中呈现。我在网上搜索过,这似乎是常见的方式

const Index=()=>{
常量[showreelActive,setShowreelActive]=useState(false)
常量[aboutUsActive,setAboutUsActive]=useState(false)
const vidRef=useRef()
useffect(()=>{
const video=vidRef.current
video&&video.play()
},[showreelActive])
const playshowleel=()=>{
aboutUsActive&&setAboutUsActive(false)
设置ShowReelActive(真)
gsap.to(型号比例{
x:1,
y:1,,
z:1,
轻松:“power2.easeOut”,
})
}
const closeShowreel=()=>setshowreelsactive(false)
常量openAboutUs=()=>{
setAboutUsActive(真)
pauseMouseParallax=真
isMobile&(controls.enableRotate=false)
gsap.to(型号比例{
x:2,
y:2,
z:2,
轻松:“power2.easeOut”,
})
}
常数closeAboutUs=()=>{
SETABOUTUSIVE(假)
pauseMouseParallax=假
isMobile&(controls.enableRotate=true)
gsap.to(型号比例{
x:1,
y:1,,
z:1,
轻松:“power2.easeOut”,
})
}
常数鼠标按钮视差=()=>{
pauseMouseParallax=真
}
常数mouseleavutonparlax=()=>{
关于活动?(pauseMouseParallax=true):(pauseMouseParallax=false)
}
useCalcHeight()
useffect(()=>{
const container=document.querySelector(“场景”)
const initScene=()=>(scene=new THREE.scene())
常量initCamera=()=>{
常数{fov,aspectRatio,近,远}={
fov:45,
aspectRatio:container.clientWidth/container.clientHeight,
接近:0.01,
远:180,
}
摄像机=新的三个透视摄像机(视野、视角、近距离、远距离)
常数{x,y,z}={x:0,y:0,z:82}
摄像机位置设置(x,y,z)
}
常量initLight=()=>{
常量白色=新的三种颜色(0xffffff)
常量灰色=新的三种颜色(0xb9b9b9)
white.convertSRGBToLinear()
gray.convertSRGBToLinear()
半球光=新的三个半球光(白色、灰色、2.93)
半光灯。位置。设置(-7,25,13)
场景。添加(半光)
}
常量initRenderer=()=>{
让antiAlias=window.devicePixelRatio>1?false:true
renderer=new THREE.WebGLRenderer({
反别名:反别名,
powerPreference:“高性能”,
阿尔法:是的,
})
renderer.physicallyCorrectLights=true
renderer.outputenencoding=3.sRGBEncoding
renderer.gammaFactor=2.2
renderer.setPixelRatio(window.devicePixelRatio>1?2:1)
renderer.setClearColor(0xffffff,0)
renderer.setSize(container.clientWidth、container.clientHeight)
container.appendChild(renderer.doElement)
}
常量initControls=()=>{
控件=新的轨道控件(摄影机、渲染器.doElement)
controls.enableRotate=isMobile&!pauseMouseParallax?真:假
controls.enableDamping=true
控制。阻尼系数=0.05
controls.enableZoom=false
controls.enableKeys=false
controls.enablePan=false
controls.minPolarAngle=0.99
controls.maxPolarAngle=Math.PI/1.6
controls.minAzimuthAngle=-Math.PI/4
controls.maxazimutangle=Math.PI/4
}
//负荷gltf模型
常量initModel=()=>{
const loader=new GLTFLoader()
const modelName=“model.gltf”
装载机(
`模型/网站_models/${modelName}`,
gltf=>{
model=gltf.scene.children[0]
模型位置集(0,5.5,0)
场景.添加(模型)
const windmillName=“Roundcube001”
const findModel=name=>{
返回model.children.find(object=>object.name==name)
}
const windmill=findModel(windmill名称)
const windmilly position=windmill.position.y
常数windmillTL=gsap
.timeline({暂停:true})
.至(风车位置){
y:windmillYposition-windmillYposition*0.15,
时长:1.45,
重复:-1,
重复延迟:0.8,
轻松:“power1.inOut”,
yoyo:没错,
})
常数视差鼠标=e=>{
常数{offsetX,offsetY,target}=e
常量{clientWidth,clientHeight}=target
const xPos=offsetX/clientWidth-0.5
const yPos=偏移量/客户端重量-0.5
!暂停使用视差&&
gsap.to(型号旋转、{
x:yPos/12,
y:xPos/9,
轻松:“power1.out”,
})
}
常量ObjectMouseParalax=()=>{
window.addEventListener(“mousemove”,e=>parallaxMouse(e))
}
gsap
.时间表({
默认值:{ease:“power2.easeOut”},
未完成:()=>{
!isMobile&&object