Atlaslog
Atlaslog / Field Notes / Loading & display
Field note · Loading & display

20 MB GeoJSON parsed synchronously freezes the main thread for 8 s

Quick answer

fetch takes only 600 ms, but L.geoJSON creates 120,000 path objects, computes bounds and binds events, locking the page for about 8 s. JSON.parse is not the bottleneck; per-feature vector object creation is.

Last verified 2026-11-03 · Multiple versions · Cite this page
Applies to: Leaflet 1.9.x · Mapbox GL JS 2.15 · turf.js 7.x
Symptom
Checklist
  1. Record the load in the Performance panel and see whether the long task sits in parsing or rendering.
  2. Timestamp after fetch and before L.geoJSON to separate network from parse cost.
  3. Count features and total vertices; above 500k vertices requires simplification first.
  4. Reduce to 5,000 features and retest; if the freeze disappears it is a volume problem.
  5. Check the renderer: the Leaflet SVG renderer degrades past about 10,000 paths.
Fix

Simplify geometry with mapshaper -simplify, clip to the current viewport, or switch to a Canvas renderer or vector tiles; when all data must stay, add features in batches inside requestIdleCallback.

Code
const t0 = performance.now();
const res = await fetch('/data/districts.geojson');
const text = await res.text();
const t1 = performance.now();          // 网络 + 下载
const fc = JSON.parse(text);
const t2 = performance.now();          // 解析
L.geoJSON(fc).addTo(map);
const t3 = performance.now();          // 建对象
console.log('fetch', t1 - t0, 'parse', t2 - t1, 'render', t3 - t2);
// npx mapshaper districts.geojson -simplify 10% keep-shapes -o precision=0.0001 out.geojson
const b = map.getBounds();
fetch(`/api/districts?bbox=${b.getWest()},${b.getSouth()},${b.getEast()},${b.getNorth()}`);
L.geoJSON(fc, { renderer: L.canvas({ padding: 0.5 }) }).addTo(map);
// Mapbox GL JS + vector tiles 可承载 10 万级要素
Watch out
All 120 field notesChinese originalRunnable examples
English edition written for Atlaslog from the original Chinese field note. Code is unchanged and runs as-is.
Cite this page

Atlaslog (2026). 20 MB GeoJSON parsed synchronously freezes the main thread for 8 s. https://www.jingweizhi.com/en/cookbook/geojson-large-freeze.html (accessed 2026-11-03).