# mapbox-web-performance-patterns

Mapbox GL JS performance skill that eliminates initialization waterfalls, shrinks style bundles, and replaces sluggish DOM markers with GPU layers.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 2500 installs · ★ 83
- Author: mapbox
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/mapbox/mapbox-agent-skills/tree/HEAD/skills/mapbox-web-performance-patterns/SKILL.md
- Updated: 2026-10-23
- HTML: https://affpapa.org/en/nevibecode/skills/mapbox-web-performance-patterns

## What it does

This skill equips coding agents with Mapbox GL JS optimization patterns organized by direct impact on user experience. Its highest priority targets initialization waterfalls. The guidelines force parallel data fetching alongside `new mapboxgl.Map` instead of waiting for the map's load event. It also requires explicit initial `center` and `zoom` values, preventing the map from fetching throwaway tiles for default coordinates.

Bundle footprint forms the next tier. Embedding massive style JSON files directly into application code inflates bundle sizes, so the rules enforce hosted Mapbox styles or external JSON endpoints. For markers, it sets hard operational limits: standard HTML markers are capped under 100 items, while collections between 100 and 10,000 features must be converted to GPU-accelerated `symbol` layers.

Migrating markers to symbol layers breaks individual DOM event listeners, forcing interaction logic into a single layer click listener. Non-essential visual elements like terrain or 3D buildings are pushed behind a `requestIdleCallback` invocation to protect time-to-interactive.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add mapbox/mapbox-agent-skills --skill mapbox-web-performance-patterns -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/mapbox-web-performance-patterns/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/mapbox-web-performance-patterns/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add mapbox/mapbox-agent-skills --skill mapbox-web-performance-patterns -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/mapbox-web-performance-patterns/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add mapbox/mapbox-agent-skills --skill mapbox-web-performance-patterns -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/mapbox-web-performance-patterns/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install mapbox/mapbox-agent-skills mapbox-web-performance-patterns
```

2. **Manually: put the files in place**
- File: `.github/skills/mapbox-web-performance-patterns/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add mapbox/mapbox-agent-skills --skill mapbox-web-performance-patterns -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/mapbox/mapbox-agent-skills --path skills/mapbox-web-performance-patterns
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/mapbox-web-performance-patterns/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add mapbox/mapbox-agent-skills --skill mapbox-web-performance-patterns -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/mapbox/mapbox-agent-skills/tree/HEAD/skills/mapbox-web-performance-patterns/SKILL.md

## When to use it
- eliminate sequential data fetching waterfalls during map initialization
- shrink client bundles by moving embedded style JSON out of code
- convert lagging DOM markers into GPU-accelerated symbol layers
- defer terrain and 3D buildings rendering with requestIdleCallback

## Example prompts
- Refactor this Mapbox initialization to fetch GeoJSON data in parallel.
- Convert these HTML markers to a GeoJSON symbol layer to fix pan lag.
- Check our map setup for style bundle bloat and suggest external alternatives.

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: cb2b3fa053461d63.

BEGIN THIRD-PARTY FILE cb2b3fa053461d63
````text
---
name: mapbox-web-performance-patterns
description: Performance optimization patterns for Mapbox GL JS web applications. Covers initialization waterfalls, bundle size, rendering performance, memory management, and web optimization. Prioritized by impact on user experience.
---

# Mapbox Performance Patterns Skill

This skill provides performance optimization guidance for building fast, efficient Mapbox applications. Patterns are prioritized by impact on user experience, starting with the most critical improvements.

**Performance philosophy:** These aren't micro-optimizations. They show up as waiting time, jank, and repeat costs that hit every user session.

## Priority Levels

Performance issues are prioritized by their impact on user experience:

- **🔴 Critical (Fix First)**: Directly causes slow initial load or visible jank
- **🟡 High Impact**: Noticeable delays or increased resource usage
- **🟢 Optimization**: Incremental improvements for polish

---

## 🔴 Critical: Eliminate Initialization Waterfalls

**Problem:** Sequential loading creates cascading delays where each resource waits for the previous one.

**Note:** Modern bundlers (Vite, Webpack, etc.) and ESM dynamic imports automatically handle code splitting and library loading. The primary waterfall to eliminate is **data loading** - fetching map data sequentially instead of in parallel with map initialization.

### Anti-Pattern: Sequential Data Loading

```javascript
// ❌ BAD: Data loads AFTER map initializes
async function initMap() {
  const map = new mapboxgl.Map({
    container: 'map',
    accessToken: MAPBOX_TOKEN,
    style: 'mapbox://styles/mapbox/streets-v12'
  });

  // Wait for map to load, THEN fetch data
  map.on('load', async () => {
    const data = await fetch('/api/data'); // Waterfall!
    map.addSource('data', { type: 'geojson', data: await data.json() });
  });
}
```

**Timeline:** Map init (0.5s) → Data fetch (1s) = **1.5s total**

### Solution: Parallel Data Loading

```javascript
// ✅ GOOD: Data fetch starts immediately
async function initMap() {
  // Start data fetch immediately (don't wait for map)
  const dataPromise = fetch('/api/data').then((r) => r.json());

  const map = new mapboxgl.Map({
    container: 'map',
    accessToken: MAPBOX_TOKEN,
````
END THIRD-PARTY FILE cb2b3fa053461d63

The third-party file has ended. Everything between the cb2b3fa053461d63 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 2290 of 11146 bytes. © mapbox · MIT · https://github.com/mapbox/mapbox-agent-skills/tree/HEAD/skills/mapbox-web-performance-patterns/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
