Poor Mapbox GL JS performance compared to old Mapbox.js - mapbox

I'm in the process of rewriting route-planning web app from Mapbox.js to Mapbox GL JS library.
With all the features almost implemented, it's borderline unusable due to lags, non-smooth animations and general sluggishness of the map layer.
Now, it's entirely possible I'm using the API wrong. I made a quick comparison and published it here:
https://petrnagy.github.io/index.html#automove=no
Notice the old Mapbox.js (left) is much smoother than the new Mapbox GL JS (right).
You can see the difference more clearly here where both maps are moving and zooming:
https://petrnagy.github.io/index.html#automove=yes
This is just a basic example. The app itself also features:
Dynamically styled routes (traffic, air quality, elevation)
Rich UI which overlays the map
Additional layers (eg. bicycle lanes, POIs, air quality)
With all there features, Mapbox GL JS is pretty much unusable. Unlike the old Mapbox.js, which is smooth.
Any advice for optimizing the performance appreciated!

it's important to note that the older Mapbox.js library was serving raster tiles, which get rendered server side, where the more modern Mapbox GL JS is vector based and rendered client side. Due to the nature of raster vs. vector is why you might see this "dip" in performance, if you are looking strictly at FPS, because your machine may be struggling.
Mapbox.js, like other traditional JavaScript map libraries, used the basemap-overlay mapping convention. The basemap (or baselayer) is a raster tile layer that is served already rendered from the server and overlays are often vector data that sits on top of the basemap.
Mapbox GL JS has no distinction between baselayers and overlay layers, and uses mostly vector tiles. This means that map details like labels and icons and elements like streets and buildings can be modified with JavaScript, like overlays in earlier mapping libraries. Each layer provides rules about how the renderer should draw certain data in the browser, and the renderer uses these layers to draw the map on the screen.
You can read more about the difference here: https://docs.mapbox.com/help/how-mapbox-works/web-apps/
There are also some great guides on improving performance of Mapbox GL JS maps and working with large GeoJSON sources in Mapbox GL JS

Related

How can I configure zoom extent in Mapbox when generating raster tilesets from GeoTIFF?

GOAL
I'm using Mapbox to generate raster tilesets from raw GeoTIFFs. The GeoTIFFs have a resolution such that a single pixel represents roughly a 5km x 5km square on the map. The generated raster tilesets will be hosted on Mapbox and then displayed in a Mapbox GL JS application.
PROBLEM
The issue I'm running into is extreme blurriness at high zoom levels. Below is a section of central Nigeria at about a zoom level of 7 displayed in our Mapbox GL JS app vs. the raw GeoTiff viewed in QGIS. The blurriness is of course worse at even higher zooms.
I created this raster tileset by uploading a sample GeoTIFF into Mapbox Studio (I've also used the Uploads API). The Tileset viewer in Studio displays a footnote that reads:
Zoom Extent
z0 – z5. Data will be overzoomed to z22, but simplified past 5.
I can verify this by looking at the network requests in the dev tools as I zoom in on the map – it actually seems that no new tiles are requested above z4.
QUESTION
Does Mapbox have any way to manually configure the zoom extent (specifically, the max zoom) for which raster tilesets are generated?
WHAT I'VE TRIED/RESEARCHED
I’ve clicked through to the Adjust Tileset Zoom Extent help page, which states:
For raster tilesets, the uploaded image resolution sets the minzoom
and maxzoom levels. Higher resolution images will result in the
tileset rendering at more zoom levels.
Again, the data I'm working with is of fixed resolution so I'm hoping to find a way to have tilesets generated for higher zoom levels regardless of image resolution. Mapbox Tiling Service and Tippecanoe both have custom configuration rules for specifying the max zoom (past which, simplification occurs) when creating vector tilesets. However, neither seems to handle rasters. The Uploads API does handle raster tilesets, but doesn't seem to have any zoom extent configuration options.
I've also tried adjusting various frontend configuration options in the Mapbox GL JS client like the source tileSize and the raster-resampling paint property, but to little avail. I'm definitely open to other suggestions for how to get crisp pixels at higher zoom levels, but mostly hoping there's some simple method I'm missing for getting Mapbox to generate raster tiles past z4/z5. I think even z0-z7 would be sufficient.

Custom drawing layer in Mapbox GL JS (and Leaflet)

I'm starting research to add a user feature to an existing map built in Mapbox GL JS (wrapped in an Angular 2+ application). What I need to do, is allow a user to be able to draw and rotate ellipses and text labels over the top of a map, and be able to save screen captures of the result.
I'm coming into this with no experience in Mapbox or Leaflet, so I have a lot to figure out. My first goal is to determine if I can do this in Mapbox directly (with a plugin?), of if I will need to render a canvas over the top of my map with some third-part drawing library (I have a lot of experience with those).
The obvious advantage to doing this in Mapbox directly would be that we might still be able zoom and pan.
The Mapbox-gl-draw library lets the user author features in a map, but probably not to the extent you need.
If the features the user creates don't need to live "in map space" (ie, the map is static, and the labels are statically positioned over the top, for printing), working directly on a canvas will give you much more flexibility. You'll also have access to a much wider variety of libraries.

How to access vector objects in mapbox styles(road, water etc.)?

In mapbox studio I have a lot of layers for customizations. Is there a way to access those layers programmatically with js. For example hide all WATER or ROAD layer on the map with js?
Thanks.
You can try using https://github.com/mapbox/vt2geojson to get geojson data for whichever layers you are interested in and then use this data and add styling using mapbox gl js maps.
Hope that answers your question.

What does the painting of the leaflet-described elements on a map?

I'm using Leaflet + CartoDB; I've also used Leaflet + Mapbox; and there may also be some Leaflet + GoogleMaps in my future.
My customer asked me this question: where do the Leaflet layers get painted onto the tiles? Is that done by Leaflet? Or by the Tile engine?
Does this change if I'm using a "regular" map engine (such as Mapbox) or if I'm using something like the KML-rendering plugin?
where do the Leaflet layers get painted onto the tiles? Is that done by Leaflet?
By default (unless you're doing something weird), that happens in your web browser, which is compositing DOM elements on top of each other. You can check this by using the developer tools in your browser and inspecting the DOM elements for the tiles, and the <canvas> or <svg> with your vector geometries. They are separate DOM elements, thus your browser is doing the compositing.
Does this change if I'm using a "regular" map engine (such as Mapbox) or if I'm using something like the KML-rendering plugin?
Not really. Mapbox-gl-js uses insane amounts of WebGL, so that means that the brunt of the workload moves from the browser's compositor to a WebGL stack. It still happens in the web browser, albeit in a different part of the browser.
There is no "KML rendering plugin" for leaflet, just KML loading plugins. Vector geometries are still rendered in a <canvas> or <svg> separate from the image tiles for the basemap, then composited.
You can, of course, run your own tile server (with software such as Geoserver, Mapserver, Mapproxy, mapnik+mod_tile, tirex, tilestream, or dozens of others). In that case, you obviously know you are rasterizing your data into tiles.

can we use leaflet 1 beta for vector tiles without mapbox GL?

I am still learning more about leaflet 1. I went through the change log saw a lot of improvement was done for vector.
Does leaflet 1 have it's own way for vector tiles without using Mapbox GL?
Leaflet can't do that out-of-the-box but you could use the vectortile plugin:
A Leaflet Plugin that renders Mapbox Vector Tiles on HTML5 Canvas. Though there is extensive use of MapboxVectorTiles in Mapnik PNG tile rendering as well as MapboxGL, there is a strange lacking of libraries that integrate these vector tiles directly into Leaflet. Search no more, the library you have been looking for is here!
https://github.com/SpatialServer/Leaflet.MapboxVectorTile