Skip to content

Commit

Permalink
Add prop to improve performance of MapView (#800)
Browse files Browse the repository at this point in the history
* Set `tracksViewChanges` prop automatically

* Move out of delayed region and add to useEffect

* Refactor tracksViewChanges and allow disable using prop

* Update snapshots
  • Loading branch information
YoussefHenna authored Oct 12, 2023
1 parent cfccc29 commit 69d8e28
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
10 changes: 10 additions & 0 deletions packages/maps/src/__tests__/MapView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
<Marker
coordinate={
Expand All @@ -195,6 +196,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
],
[
Expand All @@ -206,6 +208,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
<Marker
coordinate={
Expand All @@ -215,6 +218,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
],
]
Expand Down Expand Up @@ -247,6 +251,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
<Marker
coordinate={
Expand All @@ -256,6 +261,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
],
[
Expand All @@ -267,6 +273,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
<Marker
coordinate={
Expand All @@ -276,6 +283,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
],
]
Expand Down Expand Up @@ -332,6 +340,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
<Marker
coordinate={
Expand All @@ -341,6 +350,7 @@ describe("MapView tests", () => {
}
}
onPress={[Function]}
tracksViewChanges={true}
/>,
],
]
Expand Down
34 changes: 32 additions & 2 deletions packages/maps/src/components/MapView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export interface MapViewProps<T>
longitude?: number;
autoClusterMarkers?: boolean;
autoClusterMarkersDistanceMeters?: number;
// Improves performance when panning by temporarily preventing markers from tracking view changes
// See `tracksViewChanges`: https://github.com/react-native-maps/react-native-maps/blob/master/docs/marker.md#props
disableTrackViewChangesWhenPanning?: boolean;
markersData?: T[];
keyExtractor?: (item: T, index: number) => string;
renderItem?: ({ item, index }: { item: T; index: number }) => JSX.Element;
Expand All @@ -59,6 +62,7 @@ const MapViewF = <T extends object>({
loadingEnabled = true,
autoClusterMarkers = false,
autoClusterMarkersDistanceMeters = 1000,
disableTrackViewChangesWhenPanning = true,
markersData,
keyExtractor,
renderItem,
Expand All @@ -73,6 +77,8 @@ const MapViewF = <T extends object>({
animateToLocation: (location: ZoomLocation) => void;
mapRef: React.RefObject<MapViewComponent>;
}) => {
const [markerTracksViewChanges, setMarkerTracksViewChanges] =
React.useState(true);
const [currentRegion, setCurrentRegion] = React.useState<Region | null>(null);
const delayedRegionValue = useDebounce(currentRegion, 300);

Expand Down Expand Up @@ -235,6 +241,7 @@ const MapViewF = <T extends object>({
};

callOnRegionChange();

// onRegionChange excluded to prevent calling on every rerender when using an anonymous function (which is most common)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [delayedRegionValue]);
Expand Down Expand Up @@ -283,6 +290,16 @@ const MapViewF = <T extends object>({
initialCamera={camera}
loadingEnabled={loadingEnabled}
onRegionChange={setCurrentRegion}
onTouchStart={() => {
if (disableTrackViewChangesWhenPanning) {
setMarkerTracksViewChanges(false);
}
}}
onTouchEnd={() => {
if (disableTrackViewChangesWhenPanning) {
setMarkerTracksViewChanges(true);
}
}}
onPress={(event) => {
const coordinate = event.nativeEvent.coordinate;
onPress?.(coordinate.latitude, coordinate.longitude);
Expand All @@ -292,7 +309,12 @@ const MapViewF = <T extends object>({
>
{markers.map((marker, index) =>
renderMarker(
marker.props,
{
...marker.props,
tracksViewChanges: disableTrackViewChangesWhenPanning
? markerTracksViewChanges
: undefined,
},
index,
getMarkerRef(getMarkerIdentifier(marker.props)),
() => dismissAllOtherCallouts(getMarkerIdentifier(marker.props))
Expand All @@ -311,7 +333,13 @@ const MapViewF = <T extends object>({
}}
>
{clusters.map((cluster, index) => (
<React.Fragment key={index}>{cluster}</React.Fragment>
<React.Fragment key={index}>
{React.cloneElement(cluster, {
tracksViewChanges: disableTrackViewChangesWhenPanning
? markerTracksViewChanges
: undefined,
})}
</React.Fragment>
))}
</MapMarkerContext.Provider>

Expand All @@ -338,6 +366,8 @@ const MapViewF = <T extends object>({
showsCompass,
style,
zoom,
markerTracksViewChanges,
disableTrackViewChangesWhenPanning,
]
);

Expand Down
18 changes: 13 additions & 5 deletions packages/maps/src/components/marker-cluster/MapMarkerCluster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ import { MapViewContext } from "../MapViewCommon";
import { flattenReactFragments } from "@draftbit/ui";
import { MapMarkerContext } from "../MapView";

interface MapMarkerClusterProps {
tracksViewChanges?: boolean;
}

/**
* Component that clusters all markers provided in as children to a single point when zoomed out, and shows the markers themselves when zoomed in
* Renders a default component that shows the number of components inside cluster
*
* Also accepts MapMarkerClusterView to override the rendered cluster component
*/
const MapMarkerCluster: React.FC<React.PropsWithChildren> = ({
children: childrenProp,
}) => {
const MapMarkerCluster: React.FC<
React.PropsWithChildren<MapMarkerClusterProps>
> = ({ children: childrenProp, tracksViewChanges }) => {
const { region, animateToLocation } = React.useContext(MapViewContext);

const children = React.useMemo(
Expand Down Expand Up @@ -75,14 +79,18 @@ const MapMarkerCluster: React.FC<React.PropsWithChildren> = ({
longitude,
children: clusterView,
onPress,
tracksViewChanges,
})}
</MapMarkerClusterContext.Provider>
);
}}
>
{markers.map((marker, index) =>
renderMarker(marker.props, index, getMarkerRef(marker.props), () =>
onMarkerPress(marker.props)
renderMarker(
{ ...marker.props, tracksViewChanges },
index,
getMarkerRef(marker.props),
() => onMarkerPress(marker.props)
)
)}
</MarkerClusterer>
Expand Down

0 comments on commit 69d8e28

Please sign in to comment.