Closed bkiac closed 2 years ago
I tested it on more environments, and it seems like there is only a substantial difference in Chrome + Linux for some reason.
I can reproduce this issue with the example attached and on my app. Using CPU throttling(4x) on Chrome makes the difference even more obvious.
The screen capture below is without throttling.
Tech | Version |
---|---|
Chrome | 81.0.4044.138 |
OS | OSX Catalina(10.15.6) |
I am too having this issue (and as previously referenced similar to #1000). I will also note that I ran into this issue awhile back (several months) but just scrapped it and went with Leaflet because I did not have time to dig and figured that it was my implementation. However, the native MapboxGL seems to improve things quite a bit (some lag but I'm running it full-screen on a 27" 4K monitor with ~50 tabs open).
Right now, I'm just interested in running this for a side project, but do want to begin moving away from Leaflet/VectorGrid on a much bigger endeavor so I'll be monitoring this.
Can someone speak on the main disadvantages with bootstrapping MapboxGL yourself, as opposed to leveraging this library? I'm not at all trying to discount the library just making sure I understand where the discrepancy could be. This library is really 'just' a wrapper on the initialization and provides convenient hooks into the management of viewport state?
edit: I see that there is a whole suite of components so that's obviously a big advantage
The major difference, and probably where the performance issue originates, is that the camera state of ReactMapGL is managed in React, instead of mapbox-gl. The way mapbox-gl is written is fundamentally incompatible with React, as there are two independent rendering cycles: React's rendering logic, and Mapbox's own animation loop. When you update component props/states, react-map-gl has to synchronize the rendering of React components and the map itself. We have two options:
We currently use the first approach. This means that redraws happen at React's discretion. React may decide to render more than necessary than Mapbox would on its own, failing to account for how expensive the draw call is.
If you are using mapbox as nothing but a map display, generally speaking you do not need this library. If you are trying to match the map with any other React component, you will eventually run into the same issue.
We're running into this issue as well, using Mapbox GL and ReactMapGL in an interactive application. It seems to have gotten worse in the last few months.
I had some success in throttling viewport updates, as it seemed that the sheer quantity emitted when panning a map was flooding the InteractiveMap component to the point of it no longer rendering at all.
Some basic profiling points to a lot more of setState
in InteractiveMap than anything else, but I haven't absorbed it in depth.
Would it be viable to emit viewport state updates in reaction to motion, but to allow the GL instance to pan itself instead of being controlled by props?
You can set asyncRender={true}
on the map component. This will cause the React Markers & Popups to go out of sync during viewport updates, but have been reported to improve the render performance.
Running into this issue as well. Zooming and panning is super slow, especially with trackpads, and transitionDuration
does nothing to ameliorate the problem. It seems to be the setState
for viewport updates causing the problem.
^^ yes, we've had to throttle viewport updates for scrolling and panning events to once per 30ms, as unfortunately we have on-screen elements that go out of sync with asyncRender
. (performance did get a lot better, but the state tearing was visually unacceptable)
It's consistently choppy, but feels better than being inconsistently choppy.
IF one uses the original mapbox api and not the react library is this problem alleviated?
This is being addressed in v7.0. Please follow #1646
Just as info for any future searchers, we switched to mapbox v7 and used the uncontrolled map component, as well as using geoJSON to show markers with a datalayer (with step expressions to show different markers if needed)
With these changes we went from struggling at 200 markers (unusable at 300) to showing 1400 and is smoother than ever
Our challenges with this were:
key
prop. Its not ideal but it does the job after a fashionProgrammatic pan/zoom
You can call map.easeTo
and map.jumpTo
using a ref.
That's great, thanks for the info @Pessimistress !
I'm having a considerably lower frame rate with
react-map-gl
components compared to only usingmapbox-gl
. In Chrome, sometimes rendering takes twice as much time withreact-map-gl
. I had better results in Firefox, but it's still slower. Is this expected or am I missing something obvious about how to handle React re-renders more efficiently? Maybe #1000 is related to my problem.I put together an example and uploaded some results of the Chrome profiler.
Thanks for the help!