Saman
  • Work
  • Projects
  • Gallery
  • Blog
  • Resume
  • Notes
GitHub
  • Home
  • Projects
  • Gallery
  • Blog
  • Resume
  • Notes
←All notes
Published November 12, 20258 min readSaman Sahraei

Tile-Based Caching for Interactive Maps

How square tile keys, spatial caches, and zoom-aware fetching keep dense vendor maps responsive without blocking the UI thread.

MapsPerformanceReact
Tile-Based Caching for Interactive Maps

When a map needs to render thousands of points, the naive approach is to load everything at once. That works in demos — and collapses in production. The better model is to treat the viewport as a window into a much larger dataset and fetch only what the user can actually see.

Divide the map into squares

The viewport is split into fixed-size geographic tiles. Each tile gets a stable cache key derived from zoom bucket, latitude index, longitude index, and tile size. When the user pans, you compute which tiles intersect the bounds and check which ones are already cached.

  • ◆Cluster mode below a zoom threshold; marker mode above it
  • ◆Missing tiles batched into one padded bounds request
  • ◆In-flight deduplication so rapid pans do not spam fetches
  • ◆Cached results merged into a Map keyed by stable identifiers
The map should feel instant even when the dataset behind it is not.

Why MapLibre layers beat React markers

For cluster counts and vendor pins, GeoJSON circle layers scale far better than mounting one React component per feature. The browser paints circles natively; React only orchestrates data updates when the cache changes.

More notes

October 3, 2025

React Query Patterns for Live Portfolio Demos

Stale times, refetch intervals, and optimistic UI for dashboards that look alive without pretending to be production infrastructure.

August 21, 2025

GPU-Friendly Overlays on Top of MapLibre

Synchronising Three.js with MapLibre, instancing markers, and keeping 60 FPS when the camera moves.

June 14, 2025

Design Systems That Survive Nx Monorepos

Shared UI packages, strict boundaries, and typed tokens so landing and dashboard apps do not fork the same button twice.