可視化項目中經常會加載進模型,我的業務中,有個大樓的3D模型,一共有3個FBX模型,加起來30兆左右,使用公司之前的加載
組件加載一共耗費了將近20多秒。而且瀏覽器會卡頓
優化前:
模型顯示花了10多秒,顯示完後到能操作又消耗了10多秒,並且加載期間導致我的首屏動畫無法逐幀顯示,嚴重影響了效果的展
示,後來推測可能是js阻塞造成的,查看了之前FBX加載源碼後發現了問題所在,解析FBX二進制,加上解析樹的數據,工程量非常
之大。於是想到了利用worker解決這個問題。把所有的解析代碼抽出來所謂獨立的線程執行
核心的優化代碼:
import setData from './setData.js'
/**
* 將arraybuffer解析成fbx信息樹
* @private
*/
async function fbxParse(FBXBuffer,sourceDire){
if ( !isFbxFormatBinary( FBXBuffer ) ){
console.error("the arraybuffer of parse is not Fbx Format Binary");
return;
}
let fbxTree;
if(window.Worker){
// 創建腳本URL,內嵌worker或者可以使用相對路徑
let blob = new Blob([setData,'setData()']);
let myWorker = new Worker (window.URL.createObjectURL(blob));
// 第二個參數使用可轉讓對象進行ArrayBuffer數據傳遞,提高性性能,不過會清除當前FBXBuffer
myWorker.postMessage(FBXBuffer,[FBXBuffer]);
await new Promise ((resolve,reject)=>{
myWorker.onmessage = (event) => {
fbxTree = event.data
resolve()
}
})
} else {
fbxTree = new BinaryParser().parse( FBXBuffer ); //fbx信息樹
}
return new FBXTreeParser(sourceDire,fbxTree).parse(); //解析FBX樹數據
}
setData.js
export default `function setData(){
.........
this.addEventListener('message', function (e) {
this.postMessage(new BinaryParser().parse(e.data))
}, false)
}`
這裏setData中都是字符串,之前使用(function(){}).toString()發現使用Class類babel轉碼後window.URL.createObjectURL會報錯,暫時沒有時間研究,後續有空再解決
來看看對性能的提升:
優化前:
優化後:
而且加載完後,間隔1S左右就可以操作 比之前的性能提升了15倍左右
優化後(而且還是隻優化的一半的結果):
二次加載可以利用indexDB緩存,就不用再解析