Skip to content

Display Map Performance Metrics

Measure map performance using built-in events.

const createdAt = performance.now();

const map = new maplibregl.Map({
    container: "map",
    style: "https://demotiles.maplibre.org/style.json",
    center: [0, 0],
    zoom: 1,
});

map.on("load", () => {
    document.getElementById("load").textContent = (performance.now() - createdAt).toFixed(0) + " ms";
});

map.once("idle", () => {
    document.getElementById("idle").textContent = (performance.now() - createdAt).toFixed(0) + " ms";
});

let frameCount = 0;
let fpsStart = performance.now();
map.on("render", () => {
    frameCount++;
    const elapsed = performance.now() - fpsStart;
    if (elapsed >= 1000) {
        document.getElementById("fps").textContent = Math.round(frameCount * 1000 / elapsed);
        frameCount = 0;
        fpsStart = performance.now();
    }
});
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Display Map Performance Metrics</title>
<meta property="og:description" content="Measure map performance using built-in events." />
<meta property="og:created" content="2026-03-29" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script>
<style>
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
    #metrics {
        position: absolute;
        top: 10px;
        left: 10px;
        background: white;
        padding: 10px 14px;
        border-radius: .4rem;
        font-family: sans-serif;
        font-size: 14px;
        z-index: 100;
    }
    #metrics div { margin: 4px 0; }
    #metrics span { font-weight: bold; }
</style>
</head>
<body>
<div id="map"></div>
<div id="metrics">
    <div>Load: <span id="load"></span></div>
    <div>Idle: <span id="idle"></span></div>
    <div>FPS: <span id="fps"></span></div>
</div>

<script>
    const createdAt = performance.now();

    const map = new maplibregl.Map({
        container: "map",
        style: "https://demotiles.maplibre.org/style.json",
        center: [0, 0],
        zoom: 1,
    });

    map.on("load", () => {
        document.getElementById("load").textContent = (performance.now() - createdAt).toFixed(0) + " ms";
    });

    map.once("idle", () => {
        document.getElementById("idle").textContent = (performance.now() - createdAt).toFixed(0) + " ms";
    });

    let frameCount = 0;
    let fpsStart = performance.now();
    map.on("render", () => {
        frameCount++;
        const elapsed = performance.now() - fpsStart;
        if (elapsed >= 1000) {
            document.getElementById("fps").textContent = Math.round(frameCount * 1000 / elapsed);
            frameCount = 0;
            fpsStart = performance.now();
        }
    });
</script>
</body>
</html>