Closed anliting closed 4 months ago
The main problem here is this: by specifying the position with position={{lat:0, lng:0}}
you are creating new objects with every render of the main component. Since React can't know what you meant to do, it will just see a different object being passed to the position
-prop and re-render the Marker component (at least that would be the case once you added the key
props), which then has to update the position (although the position didn't actually change). This is the part that is expensive here. If you memoize the markers for example, you won't have any such problems.
There are of course a few smaller optimizations we can add to the Marker component, but Applications still need to do their part avoiding unnecessary re-renders.
I also tried to
React.useMemo
for the Marker
array,React.memo
for Marker
,Marker
, andReact.useCallback
for onCameraChanged`,
but it still results in similar profiles. Do I miss something for it to memoize them? import React,{useState}from 'react'
import{APIProvider,Map,Marker}from '@vis.gl/react-google-maps'
+ let MemoMarker=React.memo(Marker)
export default()=>{
let[cameraProps,setCameraProps]=useState({})
+ let onCameraChanged=React.useCallback(e=>setCameraProps(e.detail))
+ let marker=React.useMemo(()=>[...Array(1000)].map((e,i)=>
+ <MemoMarker key={i} position={{lat:0,lng:0}} />
+ ),[])
return<APIProvider apiKey=''>
<Map
{...cameraProps}
- onCameraChanged={e=>setCameraProps(e.detail)}
+ onCameraChanged={onCameraChanged}
- >{[...Array(1000)].map(()=>
- <Marker position={{lat:0,lng:0}} />
- )}</Map>
+ >{marker}</Map>
</APIProvider>
}
Interesting, that is pretty much spot on, and in that case the marker-components shouldn't have to re-render at all even if the map-props are changed. I re-created that in codesandbox here: https://codesandbox.io/p/devbox/snowy-dream-hnwmyh
You can see in this example that the performance problems are coming from the google maps API itself and there's nothing we can do about that. With 1000 markers, updating the DOM for the markers seems to be the main problem. It's getting a lot better when switching to AdvancedMarker
instead, but those will have that kind of performance ceiling as well.
Target Use Case
Optimize performance.
Proposal
This is an example about a
Map
with lots ofMarker
s:If we open the webpage with performance recording, continuously pan the map, we get some profiles like this:
But when we controll its props:
We get some profiles like this:
In my intuition, these two examples would have roughly the same performance in imperative programming. But I am not sure if such an optimization in React is easy or not.
I would be grateful if it is optimized. Thank you in advance.