性能问题Vue with Leaflet和Leaflet.markercluster数千个标记

时间:2018-06-07 06:12:10

标签: vue.js leaflet leaflet.markercluster

Leaflet这是一个流行的地理图书馆。

出于某种原因,将此库与Vue一起使用时,我遇到了严重的性能问题。

问题1:

超过500个标记和页面已经开始绊倒,2,000个标记 - 强烈破坏,10,000个标记 - 无法加载。

在HTML网页上,可以安静地加载50,000个。

问题2:

Leaflet.markercluster插件非常弱,它不会折叠标记。

screenshot of map with uncollapsed markers

mounted() {
  this.initMap();
  setTimeout(() => {
    this.initLocation()
  }, 100)
},
methods: {
  initMap() {
    this.map = L.map('map').setView([38.63, -90.23], 12);
    this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      maxZoom: 19,
      attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
    });
    this.tileLayer.addTo(this.map);
  },
  initLocation() {
    this.map.locate({
      setView: true,
      maxZoom: 17
    });

    //Leaflet.markercluster
    let markers = L.markerClusterGroup();

    function r(min, max) {
      return Math.random() * (max - min) + min;
    }
    let icon = L.divIcon({
      className: 'icon'
    });
    for (let i = 0; i < 500; i++) {
      let marker = L.marker([r(53.82477192, 53.97365592), r(27.3878027, 27.70640622)], {
        icon: icon
      }).addTo(this.map);
      markers.addLayer(marker);
    }
    this.map.addLayer(markers);
  },
}

2 个答案:

答案 0 :(得分:1)

请勿将marker this.map添加到markersnew Vue({ el: '#app', data: { map: null, tileLayer: null, }, mounted() { this.initMap(); setTimeout(() => { this.initLocation() }, 100) }, methods: { initMap() { this.map = L.map(this.$refs.map).setView([53.9, 27.6], 9); this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors', }); this.tileLayer.addTo(this.map); }, initLocation() { //this.map.locate({setView: true, maxZoom: 17}); //Leaflet.markercluster let markers = L.markerClusterGroup(); function r(min, max) { return Math.random() * (max - min) + min; } let icon = L.divIcon({ className: 'icon' }); // Quick test with 5k markers: for (let i = 0; i < 5000; i++) { let marker = L.marker([ r(53.82477192, 53.97365592), r(27.3878027, 27.70640622) ], { icon: icon }) /*.addTo(this.map)*/ ; // <= do not add individual `marker` to map! markers.addLayer(marker); // <= but only to MCG } this.map.addLayer(markers); }, }, });标记群组(MCG)。

仅将它们添加到MCG,然后根据需要处理添加到地图。

&#13;
&#13;
<script src="https://unpkg.com/vue@2"></script>

<!-- Leaflet assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>

<!-- Leaflet.markercluster assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.Default.css">
<script src="https://unpkg.com/leaflet.markercluster@1.3.0/dist/leaflet.markercluster-src.js"></script>

<div id="app">
  <div ref="map" style="height: 180px"></div>
</div>
&#13;
FormsModule
&#13;
&#13;
&#13;

答案 1 :(得分:0)

为了获得更高的性能

在处理许多标记时,请确保使用markercluster的缩放功能。它们具有batch methods for adding and removing lots of markersaddLayers()removeLayers()clearLayers()。他们表现得更好。另请注意,您可以在markerClusterGroup上使用chunkedLoading选项。允许您频繁返回主线程,以使UI更加灵活。

因此,扩展上面@ghybs的答案。我会像这样修改代码段:

new Vue({
  el: '#app',
  data: {
    map: null,
    tileLayer: null,
  },
  mounted() {
    this.initMap();
    setTimeout(() => {
      this.initLocation()
    }, 100)
  },
  methods: {

    initMap() {
      this.map = L.map(this.$refs.map).setView([53.9, 27.6], 9);
      this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
      });
      this.tileLayer.addTo(this.map);
    },

    initLocation() {
      //Leaflet.markercluster
      const markerClusterGroup = L.markerClusterGroup({
        chunkedLoading: true
      }); // <= Add chunked loading here

      function r(min, max) {
        return Math.random() * (max - min) + min;
      }
      let icon = L.divIcon({
        className: 'icon'
      });

      const markers = []
      // Quick test with 5k markers:
      for (let i = 0; i < 5000; i++) {
        let marker = L.marker([
          r(53.82477192, 53.97365592),
          r(27.3878027, 27.70640622)
        ], {
          icon: icon
        })
        markers.push(marker)
        // markers.addLayer(marker); // <= do not add individual marker to MCG
      }
      markerClusterGroup.addLayers(markers) // <= use batch method to add markers to MCG
      this.map.addLayer(markerClusterGroup);
    },
  },
});
<script src="https://unpkg.com/vue@2"></script>

<!-- Leaflet assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>

<!-- Leaflet.markercluster assets -->
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.Default.css">
<script src="https://unpkg.com/leaflet.markercluster@1.3.0/dist/leaflet.markercluster-src.js"></script>

<div id="app">
  <div ref="map" style="height: 300px"></div>
</div>

希望对其他人有帮助。