預(yù)加載是在進(jìn)入正式場(chǎng)景之前提前加載所需模型、材質(zhì)、圖片等資源的技術(shù)手段,其核心價(jià)值在于消除資源加載等待,確保場(chǎng)景首次渲染即可完整呈現(xiàn),從而提供無(wú)縫、流暢的用戶體驗(yàn)。在復(fù)雜的 Web 3D 可視化應(yīng)用中,資源預(yù)加載尤為重要,可有效解決首次加載時(shí)的卡頓、白屏及交互延遲等問(wèn)題。

預(yù)加載實(shí)現(xiàn)方案
01 基礎(chǔ)實(shí)現(xiàn)原理
HT for Web 中所有資源的請(qǐng)求都會(huì)經(jīng)過(guò) ht.Default.convertURL 方法,該方法提供了統(tǒng)一的資源請(qǐng)求入口:
■當(dāng)返回字符串路徑時(shí),框架會(huì)按此路徑發(fā)起資源請(qǐng)求;
■當(dāng)返回 {data: content} 格式對(duì)象時(shí),框架會(huì)直接使用 content 作為資源內(nèi)容。
基于此特性,我們可實(shí)現(xiàn)預(yù)加載機(jī)制。
// 資源緩存映射表
let sourceMap = {};
// 判斷是否為本地資源
functionisLocalUrl(url) {
return url.startsWith('data:') || url.startsWith('blob:');
}
// 重寫(xiě) convertURL 方法
let oldFunc = ht.Default.convertURL;
ht.Default.convertURL = function(url) {
if (isLocalUrl(url)) return url;
let source = sourceMap[url];
if (source) {
return { data: source };
}
return oldFunc(url);
};
02 資源加載策略
部分資源預(yù)加載適用于資源量較大但部分關(guān)鍵資源需要優(yōu)先加載的場(chǎng)景。
// 關(guān)鍵資源列表
let resources = [
"models/model.json",
"assets/texture.png",
"symbols/symbols.json"
]

全量資源預(yù)加載獲取所有已注冊(cè)資源進(jìn)行預(yù)加載:
functiongetAllResources() {
return [
...Object.keys(ht.Default.getImageMap()),
...Object.keys(ht.Default.getCompTypeMap()),
...Object.keys(ht.Default.getShape3dModelMap()),
...Object.keys(ht.Default.getMaterialMap()),
...Object.keys(ht.Default.getHdrTextureMap())
];
}
let allResources = getAllResources();

03 資源加載實(shí)現(xiàn)
// 資源類型判斷
const ResourceType = {
IMAGE: /.(png|jpg|gif|jpeg|bmp|svg)$/i,
BUFFER: /.(fbx|gltf|glb)$/i,
HDR: /.hdr$/i,
TGA: /.tga$/i,
JSON: /.json$/i
};
class ResourceLoader {
constructor(resources) {
this.resources = resources;
this.loaded = 0;
}
load() {
this.resources.forEach(url => {
if (ResourceType.BUFFER.test(url)) {
this.loadBuffer(url);
}
else if (ResourceType.IMAGE.test(url)) {
this.loadImage(url);
}
// 其他資源類型處理...
});
}
loadBuffer(url) {
ht.Default.xhrLoad(url, res => {
this.onResourceLoaded(url, res);
}, { responseType: 'arraybuffer' });
}
// 其他加載方法...
onResourceLoaded(url, res) {
sourceMap[url] = res;
this.loaded++;
this.onProgress(this.loaded, this.resources.length);
if (this.loaded === this.resources.length) {
this.onAllLoaded();
}
}
// 加載進(jìn)度回調(diào)
onProgress(loaded, total) {
console.log(`加載進(jìn)度: ${loaded}/${total}`);
};
onAllLoaded() {
console.log("所有資源預(yù)加載完成");
// 進(jìn)入主場(chǎng)景...
}
}

加載頁(yè)面優(yōu)化
01 進(jìn)度展示設(shè)計(jì)
class LoadingView{
constructor() {
this.initView();
}
initView(){
this.dm = new ht.DataModel();
this.view = new ht.graph.GraphView(this.dm);
let style = this.view.getView().style;
style.left = "0";
style.right = "0";
style.top = "0";
style.bottom = "0";
document.body.appendChild(this.view.getView());
}
// 更新進(jìn)度
updateProgress(percent) {
}
// 移除加載頁(yè)面
remove() {
setTimeout(() => {
this.view.getView().remove();
this.enterMainScene();
}, 1);
}
// 進(jìn)入主場(chǎng)景
enterMainScene(){
}
}
02視覺(jué)優(yōu)化建議
■進(jìn)度條設(shè)計(jì):使用圖標(biāo)實(shí)現(xiàn)平滑動(dòng)畫(huà)。

■背景動(dòng)畫(huà):添加輕量級(jí)背景動(dòng)畫(huà)提升等待體驗(yàn)。

■分段進(jìn)度:將加載過(guò)程分為資源加載、場(chǎng)景初始化等階段。
■預(yù)估時(shí)間:基于已加載時(shí)間預(yù)測(cè)剩余時(shí)間。
性能優(yōu)化方案
01 Service Worker 離線緩存
// sw.js
let CACHE_NAME = 'ht-resources-v1';
self.addEventListener('fetch', event => {
event.respondWith(caches.match(event.request).then(function (response) {
if (response !== undefined) {
return response;
} else {
return fetch(event.request).then(function (response) {
if (event.request.url.indexOf('storage') != -1) {
let responseClone = response.clone();
caches.open(CACHE_NAME).then(function (cache) {
cache.put(event.request, responseClone);
});
}
return response;
}).catch(function () {
return caches.match('./');
});
}
}));
});
self.addEventListener('activate', function (event) {
event.waitUntil(clients.claim());
event.waitUntil(
caches.keys().then(function (keyList) {
returnPromise.all(keyList.map(function (key) {
if (key !== CACHE_NAME) {
// 刪除舊緩存
return caches.delete(key);
}
}));
})
);
});
02 資源壓縮策略
■模型優(yōu)化:輕量化模型,對(duì)模型進(jìn)行減面。
■圖片優(yōu)化:圖片資源壓縮。
效果對(duì)比與總結(jié)
01 加載效果對(duì)比
預(yù)加載方案雖然初始顯示時(shí)間較長(zhǎng),但提供了更優(yōu)的整體用戶體驗(yàn):
■完整的場(chǎng)景一次性呈現(xiàn),避免零碎加載造成的視覺(jué)割裂。
■無(wú)卡頓的交互體驗(yàn),所有資源已就緒。
■可控的等待預(yù)期,進(jìn)度反饋降低用戶焦慮。
■更穩(wěn)定的性能表現(xiàn),避免運(yùn)行時(shí)資源加載導(dǎo)致的卡頓。

預(yù)加載效果

常規(guī)加載效果

02 適用場(chǎng)景
■大型 3D 場(chǎng)景:包含復(fù)雜模型和紋理的場(chǎng)景。

■儀表盤(pán)應(yīng)用:需要快速響應(yīng)的監(jiān)控系統(tǒng)。
■移動(dòng)端應(yīng)用:網(wǎng)絡(luò)條件不穩(wěn)定的環(huán)境。
■演示系統(tǒng):需要流暢演示效果的場(chǎng)合。
03 實(shí)施建議
■分階段實(shí)施:先對(duì)關(guān)鍵資源預(yù)加載,再逐步擴(kuò)展。
■性能監(jiān)控:添加加載時(shí)間統(tǒng)計(jì)和分析。
■A/B 測(cè)試:對(duì)比不同策略的實(shí)際效果。
綜上所述,本預(yù)加載方案能顯著提升 HT for Web 應(yīng)用的加載性能和用戶體驗(yàn),特別適合對(duì)流暢性要求高的可視化應(yīng)用場(chǎng)景。在實(shí)際項(xiàng)目中,應(yīng)根據(jù)資源規(guī)模和用戶場(chǎng)景靈活調(diào)整預(yù)加載策略,平衡加載時(shí)間和用戶體驗(yàn)。
圖撲軟件 (Hightopo) 長(zhǎng)期專注于 Web 可視化領(lǐng)域,自主研發(fā) HT for Web 2D 和 3D 圖形渲染引擎、低代碼數(shù)字孿生組態(tài)平臺(tái)及相關(guān)工具。目前產(chǎn)品已廣泛應(yīng)用于工業(yè)組態(tài)、電力能源、孿生工廠、電信機(jī)房、智慧交通、智慧城市、園區(qū)樓宇、智慧水務(wù)、航天軍工等行業(yè)領(lǐng)域,為客戶提供可靠的一站式數(shù)字孿生解決方案。
審核編輯 黃宇
-
可視化
+關(guān)注
關(guān)注
1文章
1353瀏覽量
22791 -
數(shù)字孿生
+關(guān)注
關(guān)注
4文章
1658瀏覽量
13974
發(fā)布評(píng)論請(qǐng)先 登錄
基于圖撲 HT 引擎:數(shù)字孿生民航飛聯(lián)網(wǎng)方案
基于圖撲 HT 數(shù)字孿生 3D 風(fēng)電場(chǎng)可視化系統(tǒng)實(shí)現(xiàn)解析
常見(jiàn)3D打印材料介紹及應(yīng)用場(chǎng)景分析
圖撲智慧汽車展示平臺(tái)全自研技術(shù)方案
圖撲邀您相聚 2025 國(guó)家工業(yè)軟件大會(huì)
玩轉(zhuǎn) KiCad 3D模型的使用
iTOF技術(shù),多樣化的3D視覺(jué)應(yīng)用
如何提高3D成像設(shè)備的部署和設(shè)計(jì)優(yōu)勢(shì)
基于 HT 的 3D 可視化智慧礦山開(kāi)發(fā)實(shí)現(xiàn)
圖撲軟件邀您相聚第二十屆中國(guó)國(guó)際中小企業(yè)博覽會(huì)
TechWiz LCD 3D應(yīng)用:微液晶分子摩擦排布
TechWiz LCD 3D應(yīng)用:撓曲電效用仿真
數(shù)字孿生低空經(jīng)濟(jì) WebGIS 無(wú)人機(jī)配送
TechWiz LCD 3D應(yīng)用:微液晶分子摩擦排布
基于 HT 2D&3D 渲染引擎的新能源充電樁可視化運(yùn)營(yíng)系統(tǒng)技術(shù)剖析
圖撲軟件 3D 場(chǎng)景預(yù)加載應(yīng)用實(shí)現(xiàn)
評(píng)論