Leaflet提升加載性能(一)

實際應用中,經常會出現海量圖層數據導致的頁面性能下降的問題,這裏我提供幾個思路,今天先從Layer層來解決好了。

我們知道,Leaflet支持svg和canvas兩種渲染器。正常來說,svg渲染適合少量的,實時配置的動態活躍圖層,canvas適合大數據量的靜態圖層(兩者都支持圖層響應),兩者在地圖zoom情況下就存在一定區別。默認情況下,Path和Layer層使用svg渲染。
出現性能下降的情況,主要還是由於過多的svg圖層疊加導致,因爲CircleMarker無法自定義圖標,大家自然而然的去選擇Maker圖層進行渲染,而這類圖層默認都是使用svg,優化Marker便是最簡單粗暴的方法了。
以下是優化步驟:

首先,Leaflet原生是不支持Marker使用canvas渲染的,因此我們需要對CircleMarker進行擴展,讓其支持自定義圖標,這裏我就不展開說了,直接給大家推介插件(我還是建議自己去寫)leaflet-canvas-markers 擴展完後,可以根據其案例使用canvasMarker,但問題是,該工具(或者說我們自己拓展的CircleMarker),是需要將Path默認設置爲canvas才能渲染,既preferCanvas: true。這種全局性的設置我是非常不建議的,假設你地圖內存在Path類的動畫(如飛線),或多或少會影響到。所以這時我們需要在不使用preferCanvas的情況下,單獨控制L.canvasMarker,並歸類至自定義Pane(用於控制層級),關於Pane的理解,大家可以看這裏

  • 所以,在批量渲染L.canvasMarker之前,我們先創建一個Pane,並設置其層級(避免被svg覆蓋,可根據業務隨時控制):
this.poiPane = this.map.createPane("poi");
this.poiPane.style.zIndex = 450;
  • Pane創建後,我們開始創建統一的渲染器,並設置該渲染器的Pane:
const poiRender = L.canvas({
   pane: "poi"
});
  • 之後給每個新創建的L.canvasMarker指定渲染器:
// 循環內
L.canvasMarker(latLng, {
    radius: 18,
    img: {
       url: iconUrl,
       size: iconSize ? iconSize : [36, 36],
       popupAnchor: [0, 0]
   },
   renderer: poiRender
})

之後只要添加到你的LayerGroup或map上就可以了。

---------------------------------------------------分割線-----------------------------------------------------

這裏需要注意,千萬不要在創建L.canvasMarker時創建L.canvas,如

L.canvasMarker(latLng, {
	...
	renderer: L.canvas()
})

這樣會導致每個圖標對應獨立的渲染器,地圖應用會變得更卡(負優化)。

完成以上步驟,我們的圖標類圖層性能將得到質的飛躍。

等有時間,再和大家分享更多有效的優化方案。

**轉載請務必標註作者Banterise,謝謝。 **

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