Cesium的3D在多个单页面运用中,内存只增不减致内存溢出题目的处理

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,这个只是用来初始化

<script>
    import Cesium from "Cesium";
    import aa from '../../static/serverconfig.json'
    import Vue from 'vue';
    //建立一个div,用来做3d的盒子
    const _div = document.createElement("div");
    _div.id = "newID";
    _div.style.display = "none";
    //挂载在body内里,因为全部体系加载的时刻,页面只要body,其他元素都还未加载
    document.body.appendChild(_div);
    //用Viewer来吸收
    const Viewer = new Cesium.Viewer("newID", {
        navigation: this.navigation,
        infoBox: this.infoBox
    })
    
    //中心部份写初始化3d须要的要领
    
    //把Viewer抛出去
    export default {
        Viewer,
    };
</script>

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 单页面运用

<template>
    <div class="GISbox" id="GISbox" ref="gisBox">
        <SmViewer ref="TestSmViewer"></SmViewer>
    </div>    
</template>
<script>
    import SmViewer from "../../../../components/Common/3D/3DViewer";
    export default{
        components: {SmViewer},
        mounted() {
            this.setGIS();
        },
        methods: {
            setGIS() {
                //猎取到3d的盒子
                var gis = document.getElementById("newID");
                //3d在页面中的款式,可根据本身的需求举行调解
                gis.style.display = "block";
                gis.style.position = "absolute";
                gis.style.top = "0px";
                gis.style.height = "100%";
                gis.style.width = "99%";
                //从body中移除
                document.body.removeChild(gis);
                //在本页面中的制订位置举行挂载
                document.getElementById("GISbox").appendChild(gis);
                // 加载视角,即写在3DViewer.vue中的要领,父音调
                this.$refs.TestSmViewer.setViewAngAngle();
            },
            destory3D() {
                //猎取到3d的盒子
                var gis = document.getElementById("newID");
                //隐蔽
                gis.style.display = "none";
                //从当前页面中移除
                document.getElementById("GISbox").removeChild(gis);
                //从新挂载回body
                document.body.appendChild(gis);
            }
        },
        beforeDestory(){
            //在本页面烧毁前举行这一步操纵
            this.destory3D()
        } 
</script>

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,则走第一个,不然的话,走第二个

  <keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
  </keep-alive>
  <router-view v-if="!$route.meta.keepAlive"></router-view>

然后,在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();
    }
},
    原文作者:krify
    原文地址: https://segmentfault.com/a/1190000017368378
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞