Improve the performance of Mapbox GL JS maps

Model of performance

The performance of your Mapbox GL JS maps can be measured as render time, source update time, or layer update time.

Render time

The render time refers to how quickly a map is drawn on your screen as you move around or zoom in and out of the map. Render time is a function of the number of sources, the number of layers, and the number of vertices in the features they contain:

render time = constant time + [ number of sources * per source time ] + [ number of layers * per layer time ] + [ number of vertices * per vertex time ]

Source update time

The source update time refers to how quickly changes to a GeoJSON source are visible on the map. Source update time is a function of the number of layers that use the updated source and the number of vertices in the features it contains:

source update time = constant time + [ number of layers using the source * per layer time ] + [ number of vertices * per vertex time ]

Layer update time

The layer update time refers to how quickly changes to a layer, using runtime styling, are visible on the map. Layer update time is a function of the number of vertices in the features the layer contains:

layer update time = constant time + [ # of vertices in the layer's source * per vertex time ]

Strategies for improving performance

When looking for opportunities to improve the performance of your map, look for ways in which you can reduce the number of layers, number of sources, or the complexity of the features in the data that is being rendered.

Combine layers

Combining layers that use similar styles or that can be styled using data-driven styling will reduce the number of layers, in turn reducing the render time. This strategy works well for layers with many features of the same type (fill, line, circle, symbol, or fill-extrusion) that are either styled similarly or whose styles vary by the value of a specific data field. For more on data-driven styling see the Map design guide and our Graduated circle map tutorial with Mapbox GL JS data-driven styles tutorial.

Use vector tileset sources

Use vector tileset sources over GeoJSON data sources when possible. Features in vector tilesets are split into tiles which allows GL JS to load only the features that are visible on the map. Feature geometries are also simplified meaning there are fewer vertices resulting in reduced render, source update, and layer update times. This strategy works well when working with large datasets that don’t need to be updated quickly. You can create vector tilesets using the Mapbox Uploads API or by uploading data on the Mapbox Studio Tilesets page.

Combine vector tile sources

Combining sources will reduce the number of sources and, as a result, the render time. This strategy works well when you have data coming from many individual data files. You can combine vector tile sources by either using composited sources or by creating a single vector tileset source with multiple source layers.

If you are creating vector tilesets by uploading data to Mapbox Studio, you can create a style and add vector tileset sources using the Mapbox Studio style editor. Vector sources are composited by default in the Mapbox Studio style editor.

You can create a single vector tileset source with multiple source layers using the Mapbox Studio Classic desktop application or the command line tool, Tippecanoe.

Remove unused features

Only include features that are being used in the current style. This will reduce the number of vertices, in turn reducing both render time and source update time. This works well when you are using one of our template styles. You can remove unused features using style-optimized vector tiles. Style-optimized vector tiles are smaller and a great way to reduce the size of offline caches. This feature of the Mapbox Maps API removes any layers or features in the tile that are not used in the style. Learn more about style-optimized vector tiles in the Mapbox Maps API documentation.

Use a separate GeoJSON source for data that needs to be updated rapidly

When using a GeoJSON source, any update to it requires Mapbox GL JS to reprocess the entire set of data. If updates must happen quickly and only ever affect a small number of features in a GeoJSON source (for example, changing a few features’ property values or moving a single point’s location), it may be beneficial to use two sources instead: one with the full, large dataset, used by layers that don’t update, and a second one containing only the dynamic, or updated, features used by layers that are specifically showing those features. That way, when you update the dynamic source, you’re only reprocessing a small number of features.