I have a dataset of 4360 geomarkers that I want to display on the Leaflet map. CircleMarker works just fine and the performance of the constructed map is ok. However, constructing the map takes too much time (around 20 seconds). Without react it takes a fraction of second to construct the markers. Is there a some performance hint or trick that can be used to make it construct the map faster?
import * as React from 'react';
import { Component } from 'react';
import { LatLng } from 'leaflet';
import { Map, TileLayer, CircleMarker, Popup } from 'react-leaflet';
export default class Editor extends Component {
state = {
lat: 51.505,
lng: -0.09,
zoom: 13,
markers : [ ]
}
componentDidMount() {
// data.csv contains several thousands of items
fetch('data.csv')
.then(res => res.json())
.then(data => this.setState({ markers: data.items.map(v => new LatLng(v.lat, v.lng)) }));
}
render() {
const markers = this.state.markers.map((v, i) =>
<CircleMarker key={i} center={v} radius={3} />);
return (
<Map center={new LatLng(51.505, -0.09)} zoom={this.state.zoom}>
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
{markers}
</Map>
)
}
}
Direct DOM manipulation does it in a fraction of a second:
export default class ItemsMap extends React.Component {
state = { items : [ ] };
map : L.Map;
componentDidUpdate(prevProps : any, prevState : any) {
this.renderItems(this.state.items);
}
componentDidMount() {
const node : any = ReactDOM.findDOMNode(this);
this.map = L.map(node).setView([51.505, -0.09], 13);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18 }).addTo(this.map);
fetch('data.csv')
.then(res => res.json())
.then(data => this.setState({ items: data.items.map(v => new LatLng(v.lat, v.lng)) }));
}
renderItems(items : Array<any>) {
items.forEach(item => {
L.circleMarker(
[ item.lat, item.lng ],
{ radius : 3 }
).addTo(this.map);
});
}
render() {
return (
<div id="mapid" style={{ height: '100%' }} />
);
}
}