Skip to content

Tile Layers and Grid System

This document covers Leaflet's tile layer architecture, including the GridLayer base class and TileLayer implementation. It explains the tile coordinate system, URL templating, tile loading mechanisms, and caching strategies that enable efficient display of tiled map data.

For information about other layer types, see Vector Layers. For rendering system details, see Vector Rendering System.

Architecture Overview

Leaflet's tile system is built on a two-tier architecture where GridLayer provides the foundational grid management capabilities, and TileLayer implements the specific logic for loading image tiles from tile servers.

SVG
100%

GridLayer Responsibilities:

  • Tile coordinate calculations and grid management via _tileCoordsToKey(), _keyToTileCoords()
  • Tile lifecycle through _addTile(), _removeTile(), _tileReady()
  • Zoom level handling with _updateLevels(), _setView(), _clampZoom()
  • Tile caching and pruning via _pruneTiles(), _retainParent(), _retainChildren()

TileLayer Responsibilities:

  • URL template processing with getTileUrl() and Util.template()
  • Image tile creation in createTile() with async loading callbacks
  • Subdomain rotation via _getSubdomain() and retina support through Browser.retina
  • Tile server communication with error handling in _tileOnError() and errorTileUrl fallback

GridLayer Base Class

GridLayer serves as the foundation for all tiled layers in Leaflet. It manages a hierarchical structure of zoom levels, each containing a grid of tiles positioned using CSS transforms.

Core Data Structures

Diagram: GridLayer Internal State Structure

SVG
100%

The _levels object maps zoom levels to DOM containers with positioning info (origin, zoom). The _tiles object uses _tileCoordsToKey(coords) to generate string keys like '2048:1536:12' that map to tile objects containing the DOM element (el), coordinate info (coords), and state flags (current, loaded, active, retain).

Tile Coordinate System

GridLayer uses a standard web mercator tile coordinate system where each tile is identified by {x, y, z} coordinates:

  • z: Zoom level (0 = world in single tile)
  • x: Column index (west to east)
  • y: Row index (north to south)

Diagram: Tile Coordinate to Cache Key Mapping

SVG
100%

The coordinate-to-key conversion is implemented in _tileCoordsToKey() which creates string keys, while _keyToTileCoords() performs the reverse operation by parsing the key string and returning a Point with a z property.

TileLayer Implementation

TileLayer extends GridLayer to provide image tile loading from tile servers using URL templates.

URL Template System

TileLayer processes URL templates with placeholder substitution:

PlaceholderDescriptionSourceExample
{z}Zoom levelthis._getZoomForUrl()12
{x}Tile X coordinatecoords.x2048
{y}Tile Y coordinatecoords.y or inverted1536
{s}Subdomainthis._getSubdomain(coords)a, b, c
{r}Retina suffixBrowser.retina ? '@2x' : ''@2x or ``
{-y}Inverted Y coordinate_globalTileRange.max.y - coords.yFor TMS
CustomAny option keythis.options[key]User-defined

Diagram: URL Template Processing Flow

SVG
100%

The template system uses Util.template() which replaces {key} placeholders with values from the data object. Custom placeholders can be added via layer options and will be automatically included.

Tile Creation and Loading

TileLayer implements the createTile() method to generate <img> elements with async loading:

Diagram: Tile Creation and Async Loading Sequence

SVG
100%

Error handling includes fallback to options.errorTileUrl if set, and the error is passed to the done callback which triggers a tileerror event.

Tile Loading Lifecycle

The tile loading process involves coordinate calculation, tile creation, and progressive loading based on distance from viewport center.

Tile Update Process

Diagram: Tile Update and Loading Flow

SVG
100%

Tiles are sorted by distance to viewport center using coords.distanceTo(tileCenter) and loaded in that order to prioritize visible content. The _update() method uses a DocumentFragment to batch DOM insertions for better performance.

Tile Pruning and Retention

GridLayer implements sophisticated tile retention logic to balance memory usage with smooth zoom transitions:

Diagram: Tile Pyramid Retention Strategy

SVG
100%

This pyramid-based retention keeps parent tiles (up to 5 zoom levels lower) and child tiles (up to 2 zoom levels higher) for smooth zoom transitions. The retention is based on tile "active" status, which is set after tiles finish their fade-in animation.

Zoom Level Management

GridLayer coordinates with the Map to establish zoom constraints and manage multi-resolution tile display.

Zoom Bounds Integration

Diagram: Map Zoom Bounds Calculation with Layers

SVG
100%

GridLayers register themselves with the map via _addZoomLimit(), which updates _zoomBoundLayers and triggers _updateZoomLevels(). The map's effective zoom bounds combine explicit options.minZoom/maxZoom (if set) with the union of all layer zoom bounds. When a layer is removed, _removeZoomLimit() updates the bounds accordingly.

Native Zoom Clamping

The minNativeZoom and maxNativeZoom options control tile zoom level clamping for tile sources that only provide tiles at certain zoom levels:

Diagram: _clampZoom() Logic for Native Zoom Bounds

SVG
100%

For example, if a map is at zoom level 15 but maxNativeZoom: 12, GridLayer will request tiles for zoom 12 and scale them up 2³ = 8× via CSS transforms. This is calculated in _setZoomTransform() using map.getZoomScale(mapZoom, tileZoom).

Performance Considerations

GridLayer includes several optimizations for smooth tile display and efficient memory usage.

Update Throttling

Diagram: Tile Update Throttling During Map Movement

SVG
100%

The updateWhenIdle option (default true on mobile via Browser.mobile) determines whether tiles update during panning. When false, the _onMove handler is created as a throttled version of _onMoveEnd() with options.updateInterval (default 200ms) to limit update frequency during continuous map movement.

Tile Fade Animation

SVG
100%

Smooth fade-in animations improve perceived performance while coordinating with tile pruning to optimize memory usage.