mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.23k stars 2.23k forks source link

API to solve performance of real-time events #12470

Open varna opened 1 year ago

varna commented 1 year ago

Motivation

Real-time events describe various operations in computing or other processes that must guarantee response times within a specified time (deadline). I use rAF (16.7 ms) as the deadline.

Currently, Mapbox can't handle the deadline with operations as simple as pointermove event dragging a single point on the map. Frames just can't render fast enough with the current API:

image

This problem becomes insanely apparent on large screens (4k screens). As in the example provided in video:

https://user-images.githubusercontent.com/6717694/208104452-14bb3a67-4bfb-4e15-8a4b-764b4b2fae7f.mov

This creates huge dissonance between input and representation for pointer events, because of the mismatching placement of the pointer and object.

https://user-images.githubusercontent.com/6717694/208105460-71951f8c-52d0-49fe-a33d-c4d4f302b4a1.mov

This might also be problematic with other features like animations and multiplayer tools like package tracking, agent/crew management because of constant flow of information that wastes performance and battery life of devices.

Design Alternatives

Use <canvas> projection as a layer in Mapbox instead of Mapbox itself. As mentioned in https://github.com/mapbox/mapbox-gl-js/issues/2334

Design

Nolan has a nice post about high-performance input handling with pointer events and rAF. To implement something like that we need an API from Mapbox side to render data that require real-time performance. It should avoid clashing with other layers of Mapbox to avoid pointless re-renders.

Mock-Up

Concepts

Currently, more than 95% is spent on JS in the provided example. It's great for static GeoJSON, but I need additional API for performant rendering. Maybe writing some sort of Rust module that incorporates OpenGL features of Mapbox could help, idk. Need more research on this topic. I have minimal knowledge of shaders (media/game bachelor) and no knowledge of OpenGL used on web. I need some feedback from Mapbox team on the possible reuse of GL technology used in MapboxGL.

Implementation

GordoRank commented 1 year ago

Why not render the real time portion yourself, on an overlayed canvas upon mousedown/mousemove, then update the map instance on mouseup? I've done something similar myself and it works wonderfully.

Any time the user needs to change something the entity in mapbox is hidden and the overlayed canvas takes over the rendering of just the control points and lines, when the user relinquishes control, the entity in mapbox is updated and the overlayed canvas is cleared.

Just be sure to switch pointer-events auto/none at the correct times for each canvas.

djpirra commented 1 year ago

Why not render the real time portion yourself, on an overlayed canvas upon mousedown/mousemove, then update the map instance on mouseup? I've done something similar myself and it works wonderfully.

Any time the user needs to change something the entity in mapbox is hidden and the overlayed canvas takes over the rendering of just the control points and lines, when the user relinquishes control, the entity in mapbox is updated and the overlayed canvas is cleared.

Just be sure to switch pointer-events auto/none at the correct times for each canvas.

Do you have any working examples of this?

varna commented 1 year ago

Well, Mapbox is the best tool for Maps that I have found. I love how they handle labels:

Anyways, I just love the work that Mapbox team has done. There are a lot of plugins in the ecosystem that expand on this, and having a new API to deal with fast things could open up a lot of opportunities. Currently, it feels like the best tool, that allows developers to ignore low-level stuff like canvas. I invested months into learning how Mapbox works, and I really enjoy it. I would be heartbroken to replace all this labor with some half-baked homebrewn canvas solution that would have its own problems (I already had one before finding out about Mapbox, I don't wanna go back).