這個想法來源於以前開發的一個項目,該項目須要在 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/開發