我有一个要显示在Leaflet地图上的4360个地理标记的数据集。 CircleMarker可以正常工作,并且构造的地图的性能还可以。但是,构建地图会花费太多时间(大约20秒)。没有反应,只需几分之一秒即可构建标记。有一些性能提示或技巧可以用来使其更快地构建地图吗?
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>
)
}
}
直接DOM操作只需几分之一秒即可完成:
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%' }} />
);
}
}
答案 0 :(得分:0)
要考虑的一种技术是在给定地图边界内仅渲染标记的子集,它可以大大减少重新渲染组件所需的时间以及DOM的数量创建的节点:
componentDidMount() {
fetch('data.csv')
.then(res => res.json())
.then(data => {
this.allMarkers = data.items.map(v => new LatLng(v.lat, v.lng));
displayMarkers();
});
}
其中
displayMarkers() {
const map = this.mapRef.current.leafletElement;
const markers = this.allMarkers.filter(m =>
map.getBounds().contains(m)
);
this.setState({
markers: markers
});
}
另一种优化方法(特定于传单)是将preferCanvas
设置为true
在画布上而不是SVG上渲染标记:
是否应在Canvas渲染器上渲染路径。默认情况下,所有 路径是在SVG渲染器中渲染的。
<Map
preferCanvas={true}
center={new LatLng(51.505, -0.09)}
zoom={this.state.zoom}
>
...
</Map>
following demo演示了如何通过react-leaflet
答案 1 :(得分:0)
我是通过覆盖shouldComponentUpdate lifeCycle方法解决问题的,像地图这样的组件的问题是它们通常太重了。因此,如果您有很多标记和地图lee [pm rerendering,则应重写shouldComponent生命周期方法。这样,您可以确保仅在必要的属性发生更改时才重新渲染地图(昂贵的操作)。这会有所帮助。
shouldComponentUpdate(prevProps) {
return !areEqual(this.props, prevProps);
}
答案 2 :(得分:0)
我的问题稍有不同,就是在可接受的时间内渲染了点,但是平移和缩放速度非常慢。我的本机javascript应用程序工作正常。这里的建议都没有帮助。
Why is Leaflet so slow at pan and zoom inside React?
我通过将本机javascript地图应用程序放在react页面上的iframe中解决了该问题。这不是一个理想的解决方案,我希望有一个更好的解决方案,但是我的猜测是,它将需要更新传单或做出反应。