Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vector tile performance #7549

Open
4 tasks done
sandlunds opened this issue Dec 7, 2017 · 16 comments
Open
4 tasks done

Vector tile performance #7549

sandlunds opened this issue Dec 7, 2017 · 16 comments

Comments

@sandlunds
Copy link

  • I am submitting a bug or feature request, not a usage question. Go to https://stackoverflow.com/questions/tagged/openlayers for questions.
  • I have searched GitHub to see if a similar bug or feature request has already been reported.
  • I have verified that the issue is present in the latest version of OpenLayers (see 'LATEST' on https://openlayers.org/).
  • If reporting a bug, I have created a CodePen or prepared a stack trace (using the latest version and unminified code, so e.g. ol-debug.js, not ol.js) that shows the issue.

I am experimenting with mapbox vector tiles and renderMode: 'vector'. However, in certain zoom levels the frame rate of the map drops dramatically. Mapbox itself achieves better performance, and similar maps in google maps perform very well. I have no idea how they do it, but I was wondering if anyone has any leads or have investigated this issue.

I created a code pen to show the issue: https://codepen.io/anon/pen/GOazbE?&editors=1110

I did some profiling and noticed most time is spent in ol.render.canvas.Replay.

@ahocevar
Copy link
Member

ahocevar commented Dec 7, 2017

It's simply the number of canvas instructions. OpenLayers uses Canvas 2D, whereas Mapbox and Google Maps use WebGL. Google Maps also uses a technique similar to our default renderMode ('hybrid'). Any reason why you're not using the standard render mode?

@sandlunds
Copy link
Author

I see. I wanted the improved aesthetics of the 'vector' mode, which doesn't have the scaled images. I noticed that hybrid mode still has issues with stutter if you have loadTilesWhileInteracting turned on, which I like to use for other types of layers (WMS). But all in all, what I'm looking for might not be achievable with the Canvas renderer?

@ahocevar
Copy link
Member

ahocevar commented Dec 7, 2017

The frame rate drop while loading tiles is something we might be able to improve in the future. For the rendering itself, we already do all the known optimizations. You might want to have a look at the ol-mapbox-style package, which creates optimized style functions from Mapbox Style documents. That should give you decent performance, although of course a bit slower than mapbox-gl-js, and with the scaled images of the hybrid mode.

In the end, if all you're interested in is super fast vector tile rendering, mapbox-gl-js will probably better suit your needs than OpenLayers.

@sandlunds
Copy link
Author

Thank you for the information. It's not all I'm interested in, and I'm happy with openlayers overall, but I can't deny that mapbox's rendering speed is very attractive. I'll take a look at your suggestions.

I think this can be closed.

@jirihajek
Copy link

I've also wondered why OpenLayers are slower in vector maps operations. I take for granted that it isn't possible to improve the speed (much), but what I think could be improved it the responsiveness. What currently happens is that map doesn't react to user commands, like zoom or drag, even for several seconds (subject to map size and device speed), which results in a terrible user experience.

One of the main reasons seems to be the code in CanvasTileLayerRenderer.renderFrame(), where this.drawTileImage() is called in a loop. This can block JS for a long time. I wonder, isn't is possible to break this loop when taking too long (like ~18ms or so) and leave the rendering to continue later, when JS has chance to process input events, etc.?

@ahocevar
Copy link
Member

ahocevar commented Apr 1, 2020

We did some experiments in that direction already @jirihajek, and now we conditionally break out of renderQueuedTileImages_ already when we are low on frame budget. However, we removed more frame budget based conditions, because the end result was more rendering work (i.e. re-render of all points/labels for decluttering when a new tile becomes available). But afterwards we made several more renderer changes, so this concern may not be valid any more.

That said, we're open for improvement suggestions here. So if you can provide a pull request with your desired change, it will be gladly accepted. I am reopening this issue to track progress.

Another note along these lines: I have started experimenting with OffscreenCanvas, also with the goal to avoid UI blocking tasks in the main thread. See #10828 for the result.

@jirihajek
Copy link

Wow, the OffscreenCanvas example is really impressive! With some more optimizations and particularly wider browser support this seems to be the way to go.

I haven't had time to look into the breaking render loop optimizations mentioned above and to be honest, given the OffscreenCanvas performance, I'd say it doesn't make much sense to do so.

I wonder though, until this is fully working solution, has anyone considered mixed usage of MapBox with OL? The idea is to use MapBox to quickly render the vector layer map and use OL to render all the rest, then mix this in a single canvas to be shown. I haven't found such an implementation and wonder whether anyone has an insight, whether this is possible and makes sense. Thanks!

@jahow
Copy link
Contributor

jahow commented Jun 18, 2020

I wonder though, until this is fully working solution, has anyone considered mixed usage of MapBox with OL?

There is an example showing just that: https://openlayers.org/en/master/examples/mapbox-layer.html

But this relies on a Mapbox-gl-js undocumented API, so it will stay "experimental" until Mapbox-gl-js offers a safer way of syncing maps. Use at your own risk!

@jirihajek
Copy link

There is an example showing just that: https://openlayers.org/en/master/examples/mapbox-layer.html

Indeed, not sure how I'd missed this one, seems to be working fine. I don't see any problem to use this, apart from the mentioned possible issue with future MapBox upgrades.

Thanks!

@ChristianM18
Copy link

I wonder though, until this is fully working solution, has anyone considered mixed usage of MapBox with OL?

There is an example showing just that: https://openlayers.org/en/master/examples/mapbox-layer.html

But this relies on a Mapbox-gl-js undocumented API, so it will stay "experimental" until Mapbox-gl-js offers a safer way of syncing maps. Use at your own risk!

This is indeed very appealing in terms of performance. I wonder though, is there a way to use this technique with other projections than EPSG:3857 ?

Thanks!

@jirihajek
Copy link

This is indeed very appealing in terms of performance. I wonder though, is there a way to use this technique with other projections than EPSG:3857 ?

No, maybe in the future: mapbox/mapbox-gl-js#3184

eidge added a commit to eidge/glana-web that referenced this issue May 22, 2021
Unfortunately OpenLayers performance is not great with VectorTiles.

This is because it uses a canvas object to render these tiles, whereas
MapBox uses WebGL: openlayers/openlayers#7549
@cns-solutions-admin
Copy link
Contributor

I think it would be nice to use hybrid mode when zoomed out and vector mode when zoomed in:

  • the performance when zoomed out would be fine, as image tiles are used
  • when zoomed in and fewer features allow performant vector rendering, it looks better

Currently this probably could be simulated by defining two layers with min/maxResolution:

  • one with hybrid mode for low reolutions
  • one with vector mode for high resolutions.

Render mode could be changed to

  • be a function (resolution) or function (zoomLevel) or resolution or zoomLevel (not sure which of these would be best)
  • depending on the resolution/zoomLevel or return value of the function the layer is rendered in vector or hybrid mode

@ahocevar
Copy link
Member

Good suggestion, @cns-solutions-admin. We could also automatically switch modes, depending on the time spent in the previous animation frame. Because complexity of tiles not always correlates with zoom levels.

@DerZade
Copy link

DerZade commented Aug 31, 2022

With #13461 merged and released in v7 we will hopefully get a WebGL based vector tile renderer in the near future. That should improve performance drastically.

@loro2
Copy link

loro2 commented Jun 8, 2023

Hi, is there any update on a WebGL based vector tile renderer for openlayers? This would be a game-changer. Thanks!

@jahow
Copy link
Contributor

jahow commented Jun 8, 2023

An experimental renderer is in since #14445 🙂 There is currently ongoing work on webgl rendering in OpenLayers as part of a sponsoring by BSW-Hamburg and Landesbetrieb Geoinformation und Vermessung Hamburg.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants