我在地图上基于活动过滤器渲染标记时遇到了一个主要的性能问题。
我有一个数据结构,类似于
const businesses = [
{
...location,
businessType: 'Market'
},
...etc
]
目前该数据集中有150个项目。默认情况下会渲染所有标记。目前我正在随机生成标记数据。
现在,我也有可以切换的类别,如果类别被切换=>渲染该业务类型。
现在,每当我切换类别时,我的JS线程跳转到0 fps并且UI线程被阻止。
这是我目前的代码:
import React, { PureComponent } from 'react';
import { InteractionManager } from 'react-native';
import generateRandomMapData from 'utils/generateRandomMapData';
import CustomMarker from './CustomMarker';
const CENTER_OF_BERLIN = {
latitude: 52.5200,
longitude: 13.4050,
};
const RADIUS = 5000;
const AMOUNT_OF_MARKERS = 150;
class Markers extends PureComponent {
constructor(props) {
super(props);
this.state = {
markers: null
}
}
componentDidMount() {
this.interactionHandle = InteractionManager.runAfterInteractions(() => {
this.setState({ markers: generateRandomMapData(CENTER_OF_BERLIN, RADIUS, AMOUNT_OF_MARKERS) }, () => {
this.interactionHandle = null;
})
})
}
componentWillUnmount() {
if (this.interactionHandle) this.interactionHandle.cancel();
}
renderMarkers() {
const { markers } = this.state;
if (markers && markers.length) {
return markers.map((b, i) => <CustomMarker location={b.location} key={i} businessType={b.businessType} />)
}
return null;
}
render() {
return this.renderMarkers()
}
}
export default Markers;
个人标记文件
import React, { PureComponent } from 'react';
import { View, InteractionManager } from 'react-native'
import { Marker } from 'react-native-maps';
import { connect } from 'react-redux';
import SVG from 'components/svg/SVG'
const BUSINESS_COLORS = {
market: '#EC6D52',
farm: '#763DAB',
restaurant: '#C45D72',
UrbanFarm: '#4B85DD',
store: '#65A077',
}
class CustomMarker extends PureComponent {
constructor(props) {
super(props);
this.state = {
shouldRender: false
}
}
componentWillMount() {
const { businessType, categories } = this.props;
this.interactionHandle = InteractionManager.runAfterInteractions(() => {
if (this._getActiveCategories(categories).includes(businessType) !== this.state.shouldRender) {
this.setState({ shouldRender: this._getActiveCategories(categories).includes(businessType) }, () => {
this.interactionHandle = null;
});
}
});
}
componentDidUpdate() {
if (this.interactionHandle) this.interactionHandle.cancel();
const { businessType, categories } = this.props;
const { shouldRender } = this.state;
this.interactionHandle = InteractionManager.runAfterInteractions(() => {
if (this._getActiveCategories(categories).includes(businessType) !== shouldRender) {
this.setState({ shouldRender: this._getActiveCategories(categories).includes(businessType) }, () => {
this.interactionHandle = null;
})
}
});
}
componentWillUnmount() {
if (this.interactionHandle) this.interactionHandle.cancel();
}
_getActiveCategories(categories) {
const active = [];
for (let category of categories) {
if (category.active) {
active.push(category.icon)
}
}
return active;
}
render() {
const { businessType, location } = this.props;
const { shouldRender } = this.state;
const iconColor = BUSINESS_COLORS[businessType.toLowerCase()];
const opacity = shouldRender ? 1.0 : 0.0;
return (
<Marker coordinate={{ ...location }} opacity={opacity}>
<View style={{ width: 29, height: 36 }}>
<SVG icon="Marker" width="29" height="36" fill={iconColor} />
</View>
</Marker>
);
}
}
const mapStateToProps = (state) => ({
categories: state.categories
});
export default connect(mapStateToProps, {
})(CustomMarker);
类别本身存在于Redux中,并且标记基于此进行映射。
即使使用了setState
,似乎同时在25个受影响的标记上调用InteractionManager
也非常繁重。
如何优化此性能?