这个想法来源于以前开发的一个项目,该项目须要在 zoom 16 的级别下渲染 (100 * 100) 的小方格,使用高德地图的多边形覆盖物 Polygon 进行渲染,在 mac 13 寸屏幕下渲染 1k+,在外接 27 寸(不太记得多少寸了)显示屏下须要渲染近 3K 的覆盖物。vue
我尝试使用 vue-amap 这个组件库,在 1k 覆盖物的状况下须要渲染 5 秒左右,在 3k 覆盖物的渲染下会渲染 30+ 秒,甚至会让浏览器直接崩溃。我选择本身经过 AMap SDK 封装了一个组件,然而性能比 vue-amap 还要差,1k 覆盖物须要耗费 10+ 秒,若是我拿这个交给产品,他估计会打死我。git
这里有一个渲染 2000 个覆盖物 fast-amap 与 vue-amap 的对比,能够感觉一下。github
事实上,咱们在使用 Vue 开发的时候经过props将数据传递给组件或是data,而 Vue 默认会对这些数据进行deepWatch,而我放在 data 上的 Polygon 实例每次都会被 Vue 绑定,这就是形成性能下降的缘由。最后我本身封装了一个 Polygon 的渲染类,1k+覆盖物渲染在 1 秒左右,虽然解决了性能问题,但使用却很不方便,由于在业务中有太多关于渲染处理的代码,没法作到只关心数据问题,须要编写不少配置属性。浏览器
在那个项目结束以后我就想封装一个组件,然而却一直有些问题困扰着我。异步
咱们经过 props 传递的数据都会被 Vue 绑定,但咱们能够经过 clone 一份数据。在组件在 watch 数据,一旦数据变动就进行深 clone,而后实例经过 clone 数据去渲染。虽然 clone 会带来一部分消耗,然而对比数据绑定的消耗几乎微乎其微。函数
在地图组件中添加一个boolean类型的值mapLoaded,当地图加载完成以后才去渲染子组件。这时候子组件的 mounted 函数中就能够获取到地图实例。性能
在 AMap 中封装了一个地图的注册表类,当地图建立成功后将实例添加进注册表,销毁后删除注册表中的实例。而全部的地图组件都须要添加一个注册表的 ID,这样就能保证每一个组件都能获取到其对应的地图实例了。code
github: link.zhihu.com/?target=htt… 文档: txs1992.github.io/fast-amap/开发