高德地圖 web 端 JS API 遇到的坑及性能優化

【JS API V2.0】

本指望全面提升一下性能,結果發現一些硬傷,迫不得已轉到1.4.15版本,先說一下最新的v2.0的問題。

  1. 因爲務業需要規劃線路,但是這個版本中,規劃線路,並且經過中間點時,部分window 7 旗艦 chrome 報錯,報錯信息:Uncaught Error: createProgram fail  chrome 版本 81.0.4044.113(正式版本) (64 位) win7 64位即便是官方demo 也會報錯,後來和提交工單,回覆未復現,後來工期急就沒跟蹤,上線後有極少部分用戶反饋報錯
  2. LabelMarker 部分點位在地圖放大到一定程度後 不再觸發click mouseover 等事件,極少量點位會出現這種情況,目測是某些點位附近可能有什麼隱藏物吧,總之就是不觸發,但是奇怪的是,同樣的經緯度有時確是可以正確觸發事件,也可能是LabelMarker 有問題
  3. dblclick 事件 LabelMarker 的dblclick 事件 觸發的同時還會觸發click 事件,如果同時綁定click 事件 那就尷尬了,先觸發click 再觸發dblclick 事件,目測是底層對dblclick 處理有問題,click 事件應該有300ms 延時以確認是否有雙擊,這個還好,可以手動糾正,

【JS API V1.4.15】

  1. SvgMarker  在創建及地圖縮放時的處理有極大的性能問題,SvgMarker 本身不建議大量的點位應用,海量點不合適的話,建議使用LabelMarker,
  2. LabelMarker 在這個版本不提供dblclick 事件,解決辦法就是手動判斷兩次點擊是否超300ms 來斷定
  3. LabelMarker 實例 第一次調用setText setIcon 後再次調用方法不起作用,解決辦法,調用前先隱藏,調用後再顯示,
  4. LabelMaker 在某些座標下的某種縮放級別時(10+)事件不觸發,暫未發現

【性能優化】

先說結論,再說問題

  1. 關掉所有能關掉的動畫效果 (參照文檔)
  2. SvgMarker 創建時請先隱藏,添加完成後再顯示,或使用 AMap.OverlayGroup 統一處理下
  3. 如果點位超過500還是不要用SvgMarker 試試LabelMarker,並關掉動畫
  4. 千萬要慎用地圖實例 setFitView 方法,如果要用請一定要帶上參數,禁掉動畫,可以使用地圖實例的setBounds方法或setZoomAndCenter 等曲線救國,後面會說這個問題的嚴重性
  5. 認真閱讀官方文檔,很多時候是使用不規範造成的性能問題

下面來看下1.4.15版本創建4000 SvgMarker 的性能問題

8.67 s 創建用了這麼長時間。。。

再看其中一個SvgMarker性能開銷,

使用地圖實例的add 方法添加 一組SvgMarker ,顯然它們是被一個個加到頁面當中的,這些marker dom節點被不斷的加入dom必然引起性能開銷,根據dom性能優化策略,可以在創建時就指定marker 爲隱藏,後邊再顯示, 或是用官方的AMap.OverlayGroup處理,經此處理後,創建SvgMarker性能有了較大提升,4000點位用時不到3s

再往下看setFitView 的性能問題

1.9 min 。。。

再往下看這密密麻麻的是什麼

 不知道在執行什麼鬼動畫,明明感覺已經把動畫都關了呢,點進去看看,

實在是報歉,這個段源碼目測是個公共方法,一定在一個地方在調用,修改它是徒勞的,也可能是api的某個方法會觸發它,原來的業務邏輯 在4000 marker 創建後會修復一下視圖範圍,原來就直接調用了setFitView ,會不會是它呢?幹掉它,一試,果然,

怪不得就算是 v2.0 api 使用labelMarker都能卡成狗,被這貨給坑了。

雖然4000點位已經跑進3s內但爲了支撐1萬+點位的marker  新需求,顯然不能再使用SvgMarker 經過計算發現1萬點位性能開銷要6s,實在是不合適,好在1.4.15版本提供了labelMaker 作爲海量點同樣爲了達到svgMaker一樣的外觀效果,可以指定svg 作爲icon 即便你需要動態的改變它的顏色等,貼出代碼(和SvgMarker 一樣的水滴形狀)

export const getSVGSrc = (color: string) => {
    return `data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2245%22%20height%3D%2260%22%20%3E%3Cg%20%3E%3Cpath%20stroke-width%3D%220%22%20fill%3D%22${encodeURIComponent(color)}%22%20d%3D%22M22.5%2C0C10.043%2C0%2C0%2C9.75%2C0%2C21.75C0%2C41.125%2C22.5%2C60%2C22.5%2C60s22.5%2C-19.25%2C22.5%2C-38.25C45%2C9.75%2C34.958%2C0%2C22.5%2C0z%22%20%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E`
};

需要注意的是labelMaker 是不會被地圖實例的clearMap 方法所清除,要清除請使用labelsLayer 的clear 或remove 方法

下面來看labelMaker的性能開銷情況(同樣4000點位)ps:準確的說此時maker還未繪製

下面看2萬點的完整繪製時間

2萬點創建耗時

繪製耗時4S左右

諮詢高德 地圖渲染就是靠動畫幀驅動的所以有這個耗時,後邊的Microtasks目測也是繪製的一部分

暫時告一段落,可以鬆一口氣,待續其它性能問題

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章