mapbox-gl-js version:0.53.1
When using a custom layer with a webgl shader, I implemented the render method of the layer object:
class CustomLayer {
render(gl, matrix) {
/** drawing to the context **/
// this rerenders all the layers
this.map.triggerRepaint();
}
}
I can see using the Chrome performance tool that all the layers are redrawing.
https://docs.mapbox.com/mapbox-gl-js/example/add-3d-model/

For an animated custom layer on top of a static map, redrawing all layers at each frame seems aggressive. How could I refresh only the custom layer?
My use case: I coded a shader that runs at 60fps 4% CPU outside of Mapbox with low GPU activity, but I end up having to slow it down to only 15fps, 40% CPU when used as a layer in Mapbox due to the map under being fairly complex.
I mostly use this section of the documentation: https://docs.mapbox.com/mapbox-gl-js/example/custom-style-layer/
Thank you!
Seems related to #7629 Performance of animated custom WebGL layers.
Putting an overlay like DeckGL does makes it impossible to render things above the map.
After digging into the painter, its sounds to me that one thing could be done at the cost of memory:
Change https://github.com/mapbox/mapbox-gl-js/blob/master/src/render/painter.js#L404 to only go up to the layer that needs refresh + keep the layers above and below the dynamic layer in their offscreen framebuffers renders.
I made a repo with a minimal example to reproduce the experience:
https://github.com/baptistemanson/mapbox-custom-layers
@baptistemanson thanks for reporting this! It is definitely an issue. Rendering unchanging layers into a framebuffer and reusing that is something we'll probably implement but we have no timeline for when that might be.
We ended up using several maps instances (3 in most cases). Framebuffer sounds definitely more effective as displacement and pans would be perfectly in sync; but we couldn't figure out how to do it without touching at the paint process itself.
Both approaches have to group layers following a certain heuristic to limit memory footprint and number of useless redraws. Grouping by z-index + update frequency considering the type of devices to determine the number of groups was a good strategy for us if it helps.
@ansis Has there been any movement or discussion on this? It's something we're interested in seeing as well.
@measuredweighed we haven't made any progress on this but it's something we agree should be done
how would this work for custom layers?
are you thinking everything is going to end up rendering to a framebuffer and only the layers that need updating will repaint the contents of their framebuffer while everything else simply blits their old framebuffer to the screen?
@darionco you can coalesce all adjacent static layers into one texture. The texture can stay GPU side as well, it is acting like a standard, cheap GPU cache.
I used it, it works. The ergonomics to configure this with Mapbox is not practical for non GL folks though.
The same trick of rendering to a texture can be used to improve the user experience in many other situations, like reducing framerate instead of desyncing layers etc.
PS: I'm just a GL guy who bent WebGL for my use case, the Mapbox team may have figured out smarter ways to improve performance.
Most helpful comment
@measuredweighed we haven't made any progress on this but it's something we agree should be done