skills/large-scale-map-visualization/SKILL.md
Master of high-performance web map implementations handling 5,000-100,000+ geographic data points. Specializes in Leaflet.js optimization, Supercluster algorithms, viewport-based loading, canvas rendering, and progressive disclosure UX patterns.
npx skillsauth add curiositech/windags-skills large-scale-map-visualizationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Master of high-performance web map implementations handling 5,000-100,000+ geographic data points. Specializes in Leaflet.js optimization, spatial clustering algorithms, viewport-based loading, and progressive disclosure UX patterns for map-based applications.
Dataset Size Assessment:
├─ 0-100 markers
│ └─ Use vanilla Leaflet (no optimization needed)
├─ 100-1,000 markers
│ └─ Use basic clustering (react-leaflet-cluster)
├─ 1,000-10,000 markers
│ └─ Use Supercluster + viewport loading
├─ 10,000-50,000 markers
│ └─ Use Supercluster + canvas + sampling
├─ 50,000-500,000 markers
│ └─ Use Web Workers + server-side clustering
└─ 500,000+ markers
└─ Use MVT tiles + backend pre-aggregation
If zoom level < 9:
├─ Apply server-side sampling (20% random sample)
├─ Use large cluster radius (100px)
└─ Minimum 5 points per cluster
If zoom level 9-14:
├─ Use viewport-based loading
├─ Medium cluster radius (75px)
└─ Minimum 2 points per cluster
If zoom level > 14:
├─ Load all points in viewport
├─ Small cluster radius (50px)
└─ Show individual markers with labels
If mobile device detected:
├─ Enable canvas renderer (preferCanvas: true)
├─ Disable animations (zoomAnimation: false)
└─ Use 500ms debounce on map events
If desktop:
├─ Use SVG renderer for better quality
├─ Enable animations for smooth UX
└─ Use 300ms debounce on map events
| Anti-Pattern | Symptom | Detection Rule | Fix | |-------------|---------|----------------|-----| | DOM Explosion | UI freezes on pan/zoom, browser tab crashes | If >1000 DOM markers rendered simultaneously | Implement clustering with maxZoom: 16, radius: 75px | | Query Flooding | Network tab shows continuous requests during pan | If API calls triggered on every pixel movement | Add 300ms debounce to map move events | | Memory Leak | Map gets slower over time, RAM usage grows | If clusters array keeps growing without cleanup | Clear previous clusters before setting new ones | | Zoom Overload | Markers too dense at high zoom | If cluster radius same at all zoom levels | Use progressive radius: zoom<10 ? 100 : zoom<14 ? 75 : 50 | | Mobile Meltdown | App unusable on mobile devices | If frame rate <20fps on 4G device | Enable canvas renderer, disable animations, increase debounce to 500ms |
Initial State: Client reports map freezing with 50k restaurants loaded at once.
Step 1 - Assess Data Volume
Step 2 - Implement Viewport Loading
// Database function with zoom-based sampling
CREATE FUNCTION find_restaurants_in_viewport(
min_lng DOUBLE PRECISION, min_lat DOUBLE PRECISION,
max_lng DOUBLE PRECISION, max_lat DOUBLE PRECISION,
zoom_level INTEGER
)
RETURNS TABLE (id UUID, name TEXT, lat DOUBLE PRECISION, lng DOUBLE PRECISION) AS $$
BEGIN
IF zoom_level < 9 THEN
-- Sample 10% for performance
RETURN QUERY SELECT r.id, r.name, ST_Y(r.geog), ST_X(r.geog)
FROM restaurants r
WHERE r.geog && ST_MakeEnvelope(min_lng, min_lat, max_lng, max_lat, 4326)
AND random() < 0.1 LIMIT 1000;
ELSE
-- Full data at higher zoom
RETURN QUERY SELECT r.id, r.name, ST_Y(r.geog), ST_X(r.geog)
FROM restaurants r
WHERE r.geog && ST_MakeEnvelope(min_lng, min_lat, max_lng, max_lat, 4326)
LIMIT 5000;
END IF;
END; $$ LANGUAGE plpgsql;
Step 3 - Configure Supercluster with Zoom-Adaptive Settings
const getClusterOptions = (zoom: number) => ({
radius: zoom < 10 ? 120 : zoom < 14 ? 80 : 60,
maxZoom: 16, // Stop clustering at street level
minPoints: zoom < 10 ? 10 : 3 // More aggressive clustering at low zoom
});
Step 4 - Add Canvas Rendering for Mobile
const mapOptions = {
preferCanvas: true,
renderer: L.canvas({ tolerance: 15, padding: 0.3 }),
zoomAnimation: !isMobile,
fadeAnimation: !isMobile
};
Expert vs Novice Decisions:
Result: Map loads in <500ms, smooth panning at 60fps, handles zoom from world view to street level.
Performance and functionality checklist for map optimization completion:
Do NOT use this skill for:
Delegate to other skills:
database-performance-tuningreact-optimizationrest-api-designmobile-first-designdata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.