资讯专栏INFORMATION COLUMN

Cesium的3D在多个单页面应用中,内存只增不减致内存溢出问题的解决

zlyBear / 4021人阅读

摘要:解决思路既然每访问一次就会一个,那能不能就创造一个全局的,让他一直存在,通过显示与隐藏去控制在每个单页面应用中的显示呢。

1、背景:
项目使用的语言是vue+iview,因为用到了3D,所以找公司买了3d地图的产品,但是问题随之而来。把我们项目需要用到的3d地图封装成一个组件叫3dMap.vue,方便各个页面调用,vue的工作机制是在离开当前页面的时候把当前页面进行销毁,但是由于Cesium的特性,他并没有没销毁,每当访问一次,就会重新new一个Cesium.

const Viewer = new Cesium.Viewer("newID", {
    navigation: this.navigation,
    infoBox: this.infoBox
});

查看计算机进程会发现,chrome浏览器会同事跑6个以上进程,其中一个是Cesium的,它所占用的内存会随着访问次数的增加不断上涨。
2、解决思路:
既然每访问一次3dMap.vue就会new一个Cesium,那能不能就创造一个全局的Cesium,让他一直存在,通过显示与隐藏去控制在每个单页面应用中的显示呢。
3、动手:
·3.1首先创建一个全局的Cesium,起名global3D.vue,这个只是用来初始化

3.2在main.js中进行挂载

import global_ from "./components/global3D"
Vue.prototype.GLOBAL = global_

3.3 创建一个3DViewer.vue,用来接收全局的Cesium,这个文件中可以写一些设置相机视角,获取经纬度啊等等方法,

export default {
    data() {
        return {
            //接收全局的Viewer,这个Viewer是Cesium new 出来的
            viewer: this.GLOBAL.Viewer,
            scene: this.GLOBAL.Viewer.scene
        };
    },
 }

3.4 单页面应用


3.4 如果你的3d只是应用在不同的模块中,且这些模块之间没有共同的组件,如下图,在demo1模块中,demo1Page1和demo1Page2共同使用demo1Menu,且只有demo1Page1页面使用3d组件,demo2同,那么到3.3,就可以完美的解决这个问题,但是,如果你的3d是应该在同一个模块,且有共同的组件,那么在不同页面之间跳转的时候就会出现问题。比如,在demo1模块中,demo1Page1和demo1Page2共同使用demo1Menu,且demo1Page1页面和demo1Page2页面都使用了3d组件,demo2同,那么在由demo1里面的页面跳向demo2里面的页面的时候,3d就会丢失了

demo1                    demo2
    demo1Menu                demo2Menu
    demo1Page1               demo2Page1
    demo1Page2               demo2Page2

3.5 解决
解决这个问题主要是使用的vue的keep-Alive,
首先,在App.vue中,做判断,如果使用了keep-Alive,则走第一个,否则的话,走第二个

  
    
  
  

然后,在router里面,对需要被缓存的模块进行设置

           {
                path: "homePage",
                component: UMPatrolHomePage,
                name: "UMPatrolHomePage",
                meta: {
                    keepAlive: true //需要被缓存
                }
            }

最后,在单页面中写入如下,to是要去的那个页面的路径,from是从哪个页面来的那个路径,next()必须执行,否则跳转会被拦截,如果要去的页面或者from的页面使用了3d,则这个页面需要被缓存,即keep.Alive=true,成功缓存后,然后执行销毁操作,这样在不同页面之间切换的时候,就不会出现3d丢失的情况。原理感兴趣的同学可以自行搜索,网上有很多详细解说的文章

beforeRouteLeave(to, from, next) {
    if (
        to.name == "UMPatrolHomePage" ||
        to.name == "UMDetailEquipment" ||
        to.name == "虚拟巡检" ||
        to.name == "人员定位详情" ||
        to.name == "管廊安防监控列表" ||
        to.name == "管廊环境监控列表" ||
        from.name == "人员定位详情" ||
        from.name == "虚拟巡检" ||
        from.name == "UMDetailEquipment" ||
        from.name == "UMPatrolHomePage" ||
        from.name == "管廊安防监控列表" ||
        from.name == "管廊环境监控列表"
    ) {
        from.meta.keepAlive = true;
        to.meta.keepAlive = true;
        this.$destroy();
        next();
    } else {
        from.meta.keepAlive = false;
        to.meta.keepAlive = false;
        this.$destroy();
        next();
    }
},

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99990.html

相关文章

  • 企业打开Redis正确方式,来自阿里云云数据库团队解读

    摘要:未完,待续阿里云云数据库版兼容协议标准的提供持久化的内存数据库服务,基于高可靠双机热备架构可无缝扩展的集群架构以及读写分离架构,满足高读写性能场景及容量需弹性变配的业务需求。 摘要: Redis是开源的基于内存且可以持久化的分布式 Key – Value数据库。自2009年发布最初版本以来,Redis的热度只增不减,除了经常位居DB-Engines的最受欢迎Key-Value数据库榜首...

    sorra 评论0 收藏0
  • 内存泄漏

    摘要:假如没有此时会进行优化把不会被任何闭包用到的变量从词法环境中去掉从而消除内存泄漏。良好的编码方式了解一下常见现象可以减少内存泄漏现象产生同时在由于失误产生泄漏时保持清醒的思路借助进行分析定位。 引言 内存泄漏一般是由于我们编码缺陷导致的,首先明确一下内存泄漏的定义,就是应用程序不需要,但是又不能返回给操作系统以供重新分配使用,导致可用内存越来越少的现象。下面总结一下在browser端内...

    jeffrey_up 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<