setData Trashes Memory -- Dynamic Lines are Unusable
I am trying to dynamically update a simple line (using a geojson source) on each frame, and am seeing constant CPU usage of 200-300%, and animation that starts stuttering after around 20 seconds. It gets increasingly worse, with frames frequently taking several hundred ms after a few minutes runtime.
This happens in both Chrome and Firefox, on both Linux and Mac, with both Mapbox GL JS v2.14 and v3, and with all map styles I've tried.
I see multiple similar issues about this in the past; #12400, #5252, #4618, #2607, and also on Stackoverflow, so this might not be a new problem.
The profiler shows that the frame is blocked due to Major GC, and memory seems to be allocated by reloadTile and its callees in "class G extends e.VectorTileWorkerSource".
Perhaps this is by design, but in that case, is there any other way to dynamically modify a line? I'm trying to render a trivial route line from a moving vehicle on a map, which seems like a core functionality that should work efficiently? Having the UI stutter and freeze for several hundred ms at a time is not acceptable for our use case. The only workaround I've found is to use a custom layer with e.g. Three.js to render lines.
Minimum reproducible example below. It calls setData each frame with an empty line, and logs any frame taking > 30 ms. After some time (~30 seconds for me), this happens frequently, and if you leave it running for a few minutes there are much longer pauses. Some runs appear to be faster, then refreshing the page could make it slower again. (Note: In this code, I call setData 100 times per frame which seems to make the issue appear faster, but this is not needed, the same thing happens when called once per frame.)
https://jsbin.com/yegudivudi/edit?html,output
(I updated the description above with some more details after doing some debugging.)
Can confirm I'm also observing this behavior on Firefox, Chrome, and Safari (but not Edge). Even running setData just several times per second with minimal changes is enough to quickly crash mobile Chrome and Safari.
Is there any alternative way to update a source's FeatureCollection without setData while this is being looked into? Or some replacement for mapbox that won't require too much refactoring?
I ended up using a custom Three.js layer to render my lines (using Line2). It's a bit more work, but it's very customizable so you can make it look good, and perform excellent, if you put in the effort.