查看: 76|回复: 4

记录一次高德地图卡顿问题优化实操

[复制链接]

2

主题

9

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2023-1-12 12:16:59 | 显示全部楼层 |阅读模式
因为 本麻烦精 从事的行业是那种各个页面都要有高精度地图,且需要在高精度地图上进行各种花里胡哨的操作的需求,几乎每一个大屏每一个项目每一个产品都会有卡顿优化的过程(没办法产品设计的功能操作和ui的效果展示实在是不足以支撑系统的流畅运行),就用此篇文章来记录一下最近遇到的一个比较有效的实操。(可能跟地图有关可能跟地图无关,反正各类能够优化的方法和地方都用上了(T_T))
每切换一次未加载的页面,系统的内存都会不少的情况



上图可见,每一次切换页面的时候都是将近20M的一个递增,返回到之前的页面是将近10M的一个递增,这个时候移动地图是较卡顿的,可想而知当用户使用切换次数过多的时候系统必将崩溃。而又重新刷新了一下页面,内存降低至首次开始的将近40M,因此
有以下几种设想:

  • 页面切换,使用了keep-alive这种的保留,操作没有清除
  • 高德地图每一个页面都重新new了一个AMap,然后通过AMap再new一个map,切换页面的时候地图创建的这些东西没有销毁
  • 类似于setTimeout或者setInterval没有清除掉
  • 莫名位置内存问题需要排查
切换页面的时候状态保存

因为是大屏看板,所以系统并没有加keep-alive
高德地图的内容销毁

一、将页面其他内容都删掉只留地图

这一步操作发现内存还是猛增,基本可以确定卡顿就是地图自己的问题
二、高德自己的对象销毁也还存在

刚刚切换的几个页面,每个页面在onBeforeUnmount中都有map.destory()去调用高德地图的销毁,所以去打印map这个对象,高德很有意思的是销毁之后对象还在,不知道这种情况垃圾回收机制会不会识别,置为null也没有什么效果


三、class类

去搜索两个shot之间的map,想要看一下是否真的销毁掉,惊奇的发现我们用的一个class类,切换页面未被清除如下图:




ps:内存大小不要在意,一个生产一个开发,主要是看相同条件环境下面的对比
同时感叹一下命名要规范,不然shot里面这么多参数真的找不到
我们知道javascript是没有暴漏内存回收api的,全靠GC,断掉引用,所以尝试将创建的实例在页面onBeforeUnmount时候置为null,再进行查看发现没什么用,还是存在,GC应该是执行完了,前后打了四次shot,并通过配合delete的方式还是没什么用,甚至返回到前面的页面发现commonMap又创建了一次
而在页面的onBeforeUnmount以及onMounted打印赋值的对象,发现切换页面出去又回来之后本页的赋值对象是null,也就是说程序中已经没有了指向,但是并没有被回收掉。
不过很神奇的是,生产环境下的shot,就没有commonMap,然后再每个页面里面把我们使用的那个公用class类的实例=null置空,重新部署打点,发现缺失每一次的增长比之前的会少一部分,差不多就是我们置空的这个从mmonMap的实例大小,做了多次实验,目前看是有效果的,至于为什么开发环境没有成功的原因需要进一步查询。
我们还记得一个commonMap的retained Size的大小差不多是468,大概有10个,而对比开发环境,前后的数据,基本就是这个commonMap的大小,下如图,会有不准,全屏实践猜测,各位看官见谅~


四、高德内存不断递增问题

将整个系统的其他内容全部删除掉,只留各个页面的地图加载,地图上的图层以及其他内容全部去掉不用,发现,单纯的高德在线地图2.0版本的内存就是会增长,到第9个页面就会直接内存崩溃,chrome直接强制刷新黑屏,换到地图1.4.5的默认版本,内存不会增长,但是1.4.5不够支持用loca,所以就继续研究。
这个时同事发现每次增长的都是GPU,所以有可能是canvas的webgl问题,于是在页面的销毁阶段获取到地图的canvas,然后将其的webgl销毁gl.getExtension('WEBGL_lose_context').loseContext() ,可发现shot中的内存还是增长,但是速度已经不像之前那么大,对于我们这个系统已经可以支持所有页面全部走一遍。并将这个问题提报了高德的工单,至于能不能修改掉,这个就看天命了。


五、高德js引入

在开发的时候我们是使用高德官方推荐的import AMapLoader from "@amap/amap-jsapi-loader",AMapLoader.load方式加载,页面中每加载一个页面,F12dom中就会多出来两个script的高德引用,这时候才发现是通过load的方式,将script自动引入到了html下方,于是将每个页面的AMapLoader.load方法提到main.js中,每个页面中使用公用的AMap,页面加载地图的速度都快了不少,地图上的气泡图层的点击事件详情速度也快了不少,至此整个地图的优化算是有一个明显的效率提升。
高德小bug

做完这一些之后,发现高德的polygon方法使用遮罩的时候会导致后续使用这个方法边框的虚线配置没有效果,整个系统的前后polygon设置有冲突,于是又给高德提了工单,总体还是很成功的一次优化。
ps之前优化的高德loca的OD图

高德loca的加载od图因为有脉冲的动画,基本如果是地图加载完后续再对线条图层进行添加,绝对会巨卡,甚至不能使用,研究了好久他的官方图例没有项目中卡的那么明显之后,发现在map加载完之后立刻生成od图层,没有数据而已,后期使用图层提供的setData方法,效果和性能好了不是一星半点。
同理,高德的图层加载能够更换数据和位置的,不要重新生成图层,因为他们真的不清理
回复

使用道具 举报

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2023-1-12 12:17:17 | 显示全部楼层
我也遇到此问题,你上面的方法我基本都尝试过,只要多加载十来次地图,就卡的不行了。主要是新增和编辑多边形这里。
高德的增加的内存每次关闭都进行了销毁,内存也稳定下来,不再长。然而没什么用。
AMapLoader.load 公用和不公用的效果一样,我只是在一个页面测试,刷新重载地图十几次卡顿效果非常明显。加载很快,就是编辑多边形特别慢。
重载十几二十次地图后。
未开启编辑效果时,mousemove 事件非常快基本在10ms左右。  
开启新增多边形时,mousemove 直接100ms以上,明显的卡顿
有不少说降级有效果,后面考虑看看
回复

使用道具 举报

0

主题

5

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2023-1-12 12:17:25 | 显示全部楼层
销毁内存,就是调用map.destroy()之前 把多边形,点什么图册实例先清空,内存基本就下去了
回复

使用道具 举报

0

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2023-1-12 12:17:49 | 显示全部楼层
[大笑]不好意思,找到原因了,吸附多边形清空的地方有问题。(奇怪的是,整个map销毁,对于PolygonEditor没有效果,设置null和clear都没用。每次吸附增加10个实例,无意中打印了下多边形的吸附实例竟然多大几百个,夸张。)
我几乎没用过知乎,这评论发图都要会员???
这吃相简直了。那就不发图了[大笑]
回复

使用道具 举报

2

主题

4

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2023-1-12 12:18:09 | 显示全部楼层
你好  我最近用高德loca的时候  发现本地运行是好的 发布到测试环境就展示不出来  js和loca都是用的2.0版本  知道是什么原因吗
[图片]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表