项目中需要在地图中做一个风场粒子动画,原生js方法绘制的动画非常流畅,但是一放到Vue中就会变得很卡顿,帧数大概只有原来的30%,最终发现是因为map变量放在了date中重写了变量的getter/setter,导致获取某个属性或者改写某个属性的时间变长,对于动画来说,影响就非常大了。

代码中使用的是原生js的window.requestAnimationFrame()方法:告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。回调函数执行次数通常是每秒60次,执行次数通常与浏览器屏幕刷新次数相匹配。但是Vue对data中的数据做了数据劫持,因此回调函数执行的次数远远小于60次,帧数达不到,会显得动画非常卡顿。

 var AnimatedFunction = function () {
        if (canvasLayer)
            canvasLayer.needRedraw();
        globalID=requestAnimationFrame(AnimatedFunction);
    }

解决方案:将map在方法内部定义,或者深拷贝data中的值复制给map,由于一个map变量可能在多个方法内使用,也可以将map放在data和方法的外部去定义

<script type="module">
let map //外部定义
var vm = new Vue({
	el : "#app",
	data : {
		// map:'' //data中定义 getting/setting
	},
	mounted : function(){
		this.initMap();
	},
	methods:{
		initMap:function(){
         // let map = L.map("mapid", {  //方法内定义
			map = L.map("mapid", {
			          minZoom: 4,
			          maxZoom: 15,
			          crs: L.CRS.EPSG3857,
			          center: [37.005646, 114.52044],
			          zoom: 4,
					  zoomDelta: 0.5,
			          fullscreenControl: false,
			          zoomControl: false,
			          attributionControl: false
			        });
			L.tileLayer('http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}',{
                    maxZoom: 12,
                    minZoom: 4,
                    pane: 'overlayPane'
                }).addTo(map);
            var windyLayer = new Windy(map);
            windyLayer.setData(stringToDate('20200705080000'),'ground');

		},
	}
});
</script>

 

不在data中定义map后动画运行速度和原生js速度基本一致

参考链接:https://www.yinchengli.com/2019/03/24/vue-performance-problem/

Logo

前往低代码交流专区

更多推荐