当在标记内部使用组件时,React Native 地图的性能低下
Low performance on React Native maps when components are used inside of marker
我正在使用 'react-native-maps' 和 this marker clustering engine 中的 MapView 制作 React 本机地图。这是一个集群标记的组件,它一直运行良好,性能非常好:
export default class ClusterMarker extends PureComponent {
constructor(props) {
super(props)
this.state = {
tracksViewChanges: true
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (this.props !== nextProps) {
this.setState(() => ({
tracksViewChanges: true,
}))
}
}
componentDidUpdate() {
if (this.state.tracksViewChanges) {
this.setState(() => ({
tracksViewChanges: false,
}))
}
}
render() {
/*...
bunch of unrelated code where 'message', 'image', 'coordinate' and 'pointCount' are set
...*/
return (
<Marker
anchor={{x:0.5,y:0.5}}
centerOffset={{x:0.5,y:0.5}}
coordinate={coordinate}
image={image}
title={pointCount}
description={message}
tracksViewChanges={this.state.tracksViewChanges}>
{/* <Text>{pointCount}</Text> */} <-------- I want this to work just as fast
</Marker>
)
}
}
看到标记道具中的 title={pointCount}
了吗?当用户单击一个集群时,会弹出一个覆盖图,向他们显示该集群中有多少个引脚。我想将该文本从那里取出并显示在集群上。请注意,在 render inside Marker 中,有一个注释行。未注释时,视觉上它几乎可以满足需要,但在 phone 上的表现很糟糕(1 fps 会夸大其词)。
很明显问题出在文本上。我的假设是,如果文本有更新,文本组件会继续检查父组件,或者它一直无缘无故地重新呈现。以下是我尝试解决的问题列表:
- 创建一个从 Text 扩展的组件,执行相同的任务而无需奇怪的更新或重新呈现。 fps 没有增加。
- 创建一个呈现文本但从不无故更新或重新呈现的组件。 fps 没有增加。
- 添加您在上面看到的
tracksViewChanges
逻辑。这有点成功,将平均 fps 从 1 提高到 5。
- 使用其他标记聚类库(即使没有标记内的文本,所有这些库都无法以良好的性能工作)。
- 来自互联网的许多 hacky 解决方案,none 其中实际上提高了性能。
此地图目前平均处理 20,000 个引脚,随着引脚数量的增加,解决方案必须具有高性能,因为它会。
如果有人能提供帮助,我将非常高兴!
也许这不是您要找的答案,但 20k 标记是……很多。您是否考虑过根据缩放级别对标记进行聚类?您还可以过滤掉不在地图视口中的标记。
我正在使用 'react-native-maps' 和 this marker clustering engine 中的 MapView 制作 React 本机地图。这是一个集群标记的组件,它一直运行良好,性能非常好:
export default class ClusterMarker extends PureComponent {
constructor(props) {
super(props)
this.state = {
tracksViewChanges: true
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (this.props !== nextProps) {
this.setState(() => ({
tracksViewChanges: true,
}))
}
}
componentDidUpdate() {
if (this.state.tracksViewChanges) {
this.setState(() => ({
tracksViewChanges: false,
}))
}
}
render() {
/*...
bunch of unrelated code where 'message', 'image', 'coordinate' and 'pointCount' are set
...*/
return (
<Marker
anchor={{x:0.5,y:0.5}}
centerOffset={{x:0.5,y:0.5}}
coordinate={coordinate}
image={image}
title={pointCount}
description={message}
tracksViewChanges={this.state.tracksViewChanges}>
{/* <Text>{pointCount}</Text> */} <-------- I want this to work just as fast
</Marker>
)
}
}
看到标记道具中的 title={pointCount}
了吗?当用户单击一个集群时,会弹出一个覆盖图,向他们显示该集群中有多少个引脚。我想将该文本从那里取出并显示在集群上。请注意,在 render inside Marker 中,有一个注释行。未注释时,视觉上它几乎可以满足需要,但在 phone 上的表现很糟糕(1 fps 会夸大其词)。
很明显问题出在文本上。我的假设是,如果文本有更新,文本组件会继续检查父组件,或者它一直无缘无故地重新呈现。以下是我尝试解决的问题列表:
- 创建一个从 Text 扩展的组件,执行相同的任务而无需奇怪的更新或重新呈现。 fps 没有增加。
- 创建一个呈现文本但从不无故更新或重新呈现的组件。 fps 没有增加。
- 添加您在上面看到的
tracksViewChanges
逻辑。这有点成功,将平均 fps 从 1 提高到 5。 - 使用其他标记聚类库(即使没有标记内的文本,所有这些库都无法以良好的性能工作)。
- 来自互联网的许多 hacky 解决方案,none 其中实际上提高了性能。
此地图目前平均处理 20,000 个引脚,随着引脚数量的增加,解决方案必须具有高性能,因为它会。
如果有人能提供帮助,我将非常高兴!
也许这不是您要找的答案,但 20k 标记是……很多。您是否考虑过根据缩放级别对标记进行聚类?您还可以过滤掉不在地图视口中的标记。