图扑软件 3D 场景预加载应用实现

预加载是在进入正式场景之前提前加载所需模型、材质、图片等资源的技术手段,其核心价值在于消除资源加载等待,确保场景首次渲染即可完整呈现,从而提供无缝、流畅的用户体验。在复杂的 Web 3D 可视化应用中,资源预加载尤为重要,可有效解决首次加载时的卡顿、白屏及交互延迟等问题。

预加载实现方案

01 基础实现原理

HT for Web 中所有资源的请求都会经过 ht.Default.convertURL 方法,该方法提供了统一的资源请求入口:

**■**当返回字符串路径时,框架会按此路径发起资源请求;

**■**当返回 {data: content} 格式对象时,框架会直接使用 content 作为资源内容。

基于此特性,我们可实现预加载机制。

02 资源加载策略

部分资源预加载适用于资源量较大但部分关键资源需要优先加载的场景。

复制代码
// 关键资源列表
let resources = [
    "models/model.json",
    "assets/texture.png",
    "symbols/symbols.json"
]

全量资源预加载获取所有已注册资源进行预加载:

复制代码
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 资源加载实现

复制代码
// 资源类型判断
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();
        }
    }


    // 加载进度回调
  onProgress(loaded, total) {
    console.log(`加载进度: ${loaded}/${total}`);
  };
    
    onAllLoaded() {
        console.log("所有资源预加载完成");
        // 进入主场景...
    }
}

加载页面优化

01 进度展示设计

复制代码
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());
    }
    
    // 更新进度
    updateProgress(percent) {
        
    }
    
    // 移除加载页面
    remove() {
        setTimeout(() => {
            this.view.getView().remove();
            this.enterMainScene();
        }, 1);
    }
    
    // 进入主场景
    enterMainScene(){


    }
}

02视觉优化建议

**■**进度条设计:使用图标实现平滑动画。

**■**背景动画:添加轻量级背景动画提升等待体验。

**■**分段进度:将加载过程分为资源加载、场景初始化等阶段。

**■**预估时间:基于已加载时间预测剩余时间。

性能优化方案

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 资源压缩策略

■模型优化:轻量化模型,对模型进行减面。

■图片优化:图片资源压缩。

效果对比与总结

01 加载效果对比

预加载方案虽然初始显示时间较长,但提供了更优的整体用户体验:

■完整的场景一次性呈现,避免零碎加载造成的视觉割裂。

■无卡顿的交互体验,所有资源已就绪。

■可控的等待预期,进度反馈降低用户焦虑。

■更稳定的性能表现,避免运行时资源加载导致的卡顿。

预加载效果

常规加载效果

02 适用场景

**■**大型 3D 场景:包含复杂模型和纹理的场景。

**■**仪表盘应用:需要快速响应的监控系统。

**■**移动端应用:网络条件不稳定的环境。

**■**演示系统:需要流畅演示效果的场合。

03 实施建议

**■**分阶段实施:先对关键资源预加载,再逐步扩展。

**■**性能监控:添加加载时间统计和分析。

**■**A/B 测试:对比不同策略的实际效果。

综上所述,本预加载方案能显著提升 HT for Web 应用的加载性能和用户体验,特别适合对流畅性要求高的可视化应用场景。在实际项目中,应根据资源规模和用户场景灵活调整预加载策略,平衡加载时间和用户体验。

图扑软件 (Hightopo) 长期专注于 Web 可视化领域,自主研发 HT for Web 2D 和 3D 图形渲染引擎、低代码数字孪生组态平台及相关工具。目前产品已广泛应用于工业组态、电力能源、孪生工厂、电信机房、智慧交通、智慧城市、园区楼宇、智慧水务、航天军工等行业领域,为客户提供可靠的一站式数字孪生解决方案。

相关推荐
图扑数字孪生5 小时前
3D 场景预加载应用实现 | 图扑软件
信息可视化·应用·数字孪生·三维可视化·加载页
杨超越luckly6 小时前
Python应用指南:利用高德地图采集AOI数据
python·arcgis·高德地图·数据可视化·aoi数据
AI小云6 小时前
【数据操作与可视化】Matplotlib绘图-常用操作
python·数据可视化
数字冰雹21 小时前
数据中心运维新革命:图观数字孪生引擎的实战应用
人工智能·数据可视化
Emma歌小白1 天前
Power BI按列排序问题
数据可视化
全栈视界师1 天前
《机器人实践开发②:Foxglove 嵌入式移植 + CMake 集成》
c++·机器人·数据可视化
AI小云1 天前
【数据操作与可视化】Matplotlib绘图-基础功能
python·数据可视化
binlonglai1 天前
在近乎完美随机里找边:我对 PK10 的一年工程化研究
架构·数据可视化
用户41429296072392 天前
淘宝实时商品API接口:采集竞品商品详情页的价格、SKU 规格、库存数量、卖点文案、图文内容、售后政策(运费、退换货规则)、评价核心标签
数据挖掘·数据分析·数据可视化