React Native Maps 缓慢呈现标记
React Native Maps Slow Rendering of Markers
所以我遇到了 react-native-maps
在设备上或在 release
配置的模拟器上 运行 时的问题。在 debug
(设备和模拟器)上,地图效果很好;它响应迅速,控制良好等等。在 release
上,它似乎无法处理渲染多个 <MapView.Marker/>
组件(当我说多个时,我不是指数百或数千,我的意思是 < 20 ).
这是代码示例:
constructor(props) {
super(props);
this.state = {
currentPosition: global.currentPosition,
orders: [],
coordinateArray: []
};
}
componentDidMount() {
this.handleOrders().then(() => {
this.setMapToCoordinates();
});
}
async handleOrders() {
let result = await data.fetchData("...");
if (result) {
let orders = [];
let coordinateArray = [];
result.data_list.forEach(orderObject => {
let order = {
coordinates: orderParser.constructCoordinates(orderObject),
};
coordinateArray.push(order.coordinates);
orders.push(order);
});
this.setState({
orders: orders,
coordinateArray: coordinateArray
});
}
}
setMapToCoordinates(){
if (this.mapView) {
let coordinateArray = this.state.coordinateArray;
if (this.state.currentPosition) {
coordinateArray = coordinateArray.concat(this.state.currentPosition.coordinates);
}
this.mapView.fitToCoordinates(coordinateArray, {
edgePadding: {
top: 200,
right: 100,
bottom: 100,
left: 100
},
animated: animated
});
}
}
所以,这段代码中发生的事情是,当组件安装时,它执行一个 API 调用来获取一堆 orders
,其中包含 coordinates
,以及其他信息。除了将它推到 orders
之外,它还将坐标推到 coordinateArray
,它在 setMapToCoordinates()
中用于约束地图边界。
接下来,这里是这个组件的render
函数:
render() {
return (
<MapView mapType="satellite" ref={ref => { if (!this.mapView) { this.mapView = ref; }}}>
{this.state.orders.map(order => {
return <MapView.Marker key={order.id} coordinate={order.coordinates} image={require("...")} />;
})}
{this.state.currentPosition ? <MapView.Marker key={"currentPosition"} coordinate={this.state.currentPosition.coordinates} image={require("../images/pin.png")} centerOffset={{ x: 0, y: -25 }} /> : null}
</MapView>
);
}
这是操作流程:
- 组件安装、渲染
<MapView>
和 this.state.currentPosition
的单个 <MapView.Marker/>
(在早期组件中检索)
handleOrders()
被调用,更新 this.state.orders
和 this.state.coordinateArray
.
- 渲染了额外的
<MapView.Marker/>
个组件。
setMapToCoordinates()
被调用,移动地图以适应 this.state.currentPosition
和 this.state.coordinateArray
的视图。
在 debug
,此工作流没有问题,但在 release
,在第 2 步成功和第 3 步完成之间有大约 40 秒的延迟。遵循成功渲染这 ~16 个标记后,一切正常,但在加载期间,应用程序完全没有响应。此外,由于涉及导航,因此会在单个会话中多次调用此流程。
如果有人知道这个问题的原因and/or如何解决,那就太好了。在 release
方案中,我很难调试它,日志记录被禁用。
进一步参考:
react-native-maps: ^0.17.1
react-native: 0.49.3
release
方案
- iPhone 6、7 和 7+ 测试
所以,我上面的代码中没有显示的是一个简单的日志记录语句
setMapToCoordinates(){
console.log("Called!", this.mapView);
...
}
我用它来测试 this.mapView
在几种不同情况下的情况,在 debug
配置中,它记录 "Called!", ...
没有问题(this.mapView
是设置为 <MapView>
上的 ref
。
出于某种原因,在 release
配置中,这段代码在调用 this.setMapToCoordinates()
时会导致速度大幅下降,这发生在 API 调用 fetch orders
之后,以及其他操作。
所以虽然我无法回答这个问题的"why",但我可以回答"how",如果其他人遇到类似的事情,也许这可以帮助他们。
所以我遇到了 react-native-maps
在设备上或在 release
配置的模拟器上 运行 时的问题。在 debug
(设备和模拟器)上,地图效果很好;它响应迅速,控制良好等等。在 release
上,它似乎无法处理渲染多个 <MapView.Marker/>
组件(当我说多个时,我不是指数百或数千,我的意思是 < 20 ).
这是代码示例:
constructor(props) {
super(props);
this.state = {
currentPosition: global.currentPosition,
orders: [],
coordinateArray: []
};
}
componentDidMount() {
this.handleOrders().then(() => {
this.setMapToCoordinates();
});
}
async handleOrders() {
let result = await data.fetchData("...");
if (result) {
let orders = [];
let coordinateArray = [];
result.data_list.forEach(orderObject => {
let order = {
coordinates: orderParser.constructCoordinates(orderObject),
};
coordinateArray.push(order.coordinates);
orders.push(order);
});
this.setState({
orders: orders,
coordinateArray: coordinateArray
});
}
}
setMapToCoordinates(){
if (this.mapView) {
let coordinateArray = this.state.coordinateArray;
if (this.state.currentPosition) {
coordinateArray = coordinateArray.concat(this.state.currentPosition.coordinates);
}
this.mapView.fitToCoordinates(coordinateArray, {
edgePadding: {
top: 200,
right: 100,
bottom: 100,
left: 100
},
animated: animated
});
}
}
所以,这段代码中发生的事情是,当组件安装时,它执行一个 API 调用来获取一堆 orders
,其中包含 coordinates
,以及其他信息。除了将它推到 orders
之外,它还将坐标推到 coordinateArray
,它在 setMapToCoordinates()
中用于约束地图边界。
接下来,这里是这个组件的render
函数:
render() {
return (
<MapView mapType="satellite" ref={ref => { if (!this.mapView) { this.mapView = ref; }}}>
{this.state.orders.map(order => {
return <MapView.Marker key={order.id} coordinate={order.coordinates} image={require("...")} />;
})}
{this.state.currentPosition ? <MapView.Marker key={"currentPosition"} coordinate={this.state.currentPosition.coordinates} image={require("../images/pin.png")} centerOffset={{ x: 0, y: -25 }} /> : null}
</MapView>
);
}
这是操作流程:
- 组件安装、渲染
<MapView>
和this.state.currentPosition
的单个<MapView.Marker/>
(在早期组件中检索) handleOrders()
被调用,更新this.state.orders
和this.state.coordinateArray
.- 渲染了额外的
<MapView.Marker/>
个组件。 setMapToCoordinates()
被调用,移动地图以适应this.state.currentPosition
和this.state.coordinateArray
的视图。
在 debug
,此工作流没有问题,但在 release
,在第 2 步成功和第 3 步完成之间有大约 40 秒的延迟。遵循成功渲染这 ~16 个标记后,一切正常,但在加载期间,应用程序完全没有响应。此外,由于涉及导航,因此会在单个会话中多次调用此流程。
如果有人知道这个问题的原因and/or如何解决,那就太好了。在 release
方案中,我很难调试它,日志记录被禁用。
进一步参考:
react-native-maps: ^0.17.1
react-native: 0.49.3
release
方案- iPhone 6、7 和 7+ 测试
所以,我上面的代码中没有显示的是一个简单的日志记录语句
setMapToCoordinates(){
console.log("Called!", this.mapView);
...
}
我用它来测试 this.mapView
在几种不同情况下的情况,在 debug
配置中,它记录 "Called!", ...
没有问题(this.mapView
是设置为 <MapView>
上的 ref
。
出于某种原因,在 release
配置中,这段代码在调用 this.setMapToCoordinates()
时会导致速度大幅下降,这发生在 API 调用 fetch orders
之后,以及其他操作。
所以虽然我无法回答这个问题的"why",但我可以回答"how",如果其他人遇到类似的事情,也许这可以帮助他们。