nekomimi

第一次在项目里接触地图开发,虽然直接使用了百度地图的 API,但还是遇到了不少问题,而且缺少最佳实践参考,很多逻辑都是自己设计实现,渲染性能也有点低。不过最大的问题是整出了内存泄漏,麻烦死了

最大问题之内存泄漏

虽然没有做严格测试,但基本可以确定是百度地图删除覆盖物内存未释放导致的问题,花了好些天才比较完美地绕过了这个 Bug,记录一下

问题定位

  1. 刚开始以为是自定义标记的写法不对导致了内存泄漏,果断放弃了自定义标记,依然漏
  2. 开始详细排查,怀疑是 Redux 闹鬼,分步注释代码,干恁娘发现 Redux 状态更新导致了重复渲染,又着手解决重复渲染问题,最后确定 useSelector 不能用默认的全等比较,传入自带的 shallowEqual 解决问题
  3. 解决 Redux 问题后确认地图覆盖物刷新导致泄漏,开始按图层分析
  4. 预警点图标刷新并未导致泄漏,绑定的事件监听也不会漏,也没有闭包问题,确认问题出在路径折线渲染

尝试解决

  1. 定位问题花了好几天,解决问题思路倒是简单,既然不能反复添加删除,那就循环利用
初始化时保存一个折线对象数组,作为内存池,刷新时直接取内存池里已有的折线改变属性
多余的折线设置一个看不见的点位藏起来,不够的折线另外申请内存并推入对象数组

一波三折

看起来似乎很完美的解决方案,结果又被百度地图摆了一道

内存泄漏的问题的确迎刃而解,皆大欢喜,不漏了,但 是

尼玛坑爹的地图,修改折线属性、换绑点击事件之后,地图的折线干恁娘的不刷新,而且有时候还会莫名其妙的消失不见,必须拖动或者缩放一下地图才会真正刷新——我去年买了个包超耐磨

最终原子爆炸

既然你自己不刷,无他,我强制你刷

笑死,百度地图根本没有强制刷新的 API

好家伙,只能另辟蹊径了,尝试了以下几种方式

  1. 修改完属性后重置折线显隐状态(无效)
  2. 修改完重置折线颜色(无效)
  3. 修改完请来 setTimeout 异步重置折线颜色(有用,草泥马燃起来了)
  4. 所有修改都异步进行(无效,淦)

最后,采用第三种方式解决了问题,不过值得注意的是,折线刷新的时候颜色会出现闪烁,推测这里的异步处理导致了颜色刷新的时间差

Anyway,解决了最大的 Boss,不漏了,鼓掌