Zrychlení parsování velkého JSON
Shrnutí: Optimalizace ve špatném pořadí znehodnotí každou výměnu knihovny. Měřte síť, parsování a vykreslování zvlášť, poté snižte počet parsování, zmenšete payloady a streamujte.

Stručně: nejprve změřte zvlášť síť, parsování a vykreslování – většina „pomalého parsování“ se ukáže jako pomalé vykreslování – poté stoupejte po žebříčku v pořadí: méně parsování, menší payloady, streamování, worker a binární formát až nakonec.
Nezačínejte výměnou knihoven. Přidejte jeden časovač a obvykle zjistíte, že problémem je vykreslování.
Krok první: změřte fáze
const t0 = performance.now();
const response = await fetch(url);
const text = await response.text();
const t1 = performance.now();
const data = JSON.parse(text);
const t2 = performance.now();
render(data);
const t3 = performance.now();
| Dominantní fáze | Skutečný problém | Oprava |
|---|---|---|
| Síť | Payload je příliš velký | Výběr polí, stránkování, komprese |
JSON.parse |
Skutečně velký vstup | Méně parsování, streamování, worker |
| Vykreslování | Desítky tisíc uzlů najednou | Virtuální seznam, stránkování, sbalování |
Moderní prohlížeče parsují 1 MB zhruba za 5–15 ms a 10 MB za 80–150 ms. Pokud 10 MB trvá dvě sekundy, JSON.parse není vaše úzké hrdlo.
Krok druhý: parsujte méně
Nejlevnější výhra a nejvíce přehlížená.
- Přestaňte parsovat stejný payload opakovaně. Deset komponent, každá volá
JSON.parse(localStorage.getItem(...)), znamená deset parsování. Uložte výsledek jednou na úrovni modulu. - Přestaňte používat
JSON.parse(JSON.stringify(x))pro hluboké kopie. Stojí to víc než dvojnásobek objemu dat;structuredClonene. - Neparsujte v hlavním vlákně a poté neposílejte objekt do workeru.
postMessageho znovu klonuje. Pošlete surový text a nechte worker parsovat. - Žádejte méně polí. Pokud UI potřebuje tři vlastnosti, API nemá posílat tři sta.
Krok třetí: zmenšete payload
Stránkování pomocí page/size, kurzory místo hlubokého offset, souhrnná pole v seznamových endpointech. To obvykle porazí všechny frontendové optimalizace dohromady, protože snižuje síť, parsování i paměť najednou.
Krok čtvrtý: streamujte
Když data musí být zpracována jako celek a skutečně jsou velká:
import { parser } from 'stream-json';
import { streamArray } from 'stream-json/streamers/StreamArray';
const pipeline = fs.createReadStream('big.json').pipe(parser()).pipe(streamArray());
for await (const { value } of pipeline) {
await handleOne(value);
}
Více kódu a žádný náhodný přístup – vhodné jen pro zpracování záznam po záznamu.
Krok pátý: přesuňte to mimo hlavní vlákno
Parsování je rychlé, ale blokující. Dejte ho do workeru a předejte text, nikoli parsovaný objekt, jinak strukturované klonování zdvojnásobí náklady.
Krok šestý: změňte formát, až nakonec
Pro interní provoz, který je trvale v desítkách megabajtů, NDJSON streamuje přirozeně a Protobuf nebo MessagePack jsou menší a rychlejší. Oba jsou změny protokolu vyžadující koordinaci.
Nedělejte
evalJSON: nebezpečné a ne rychlejší- Serializovat JSON pro vložení do JSON: zdvojnásobí velikost
- Parsovat stovky tisíc malých řetězců ve smyčce: dávkujte je
Časté dotazy
Jak zjistit, zda je úzkým hrdlem parsování, nebo vykreslování?
Změřte zvlášť požadavek, čtení textu, JSON.parse a vykreslování pomocí performance.now() a největší fázi považujte za skutečné úzké hrdlo. Moderní prohlížeče parsují 1 MB zhruba za 5–15 ms a 10 MB za 80–150 ms, takže 10MB payload, který trvá dvě sekundy, je jen zřídka problém JSON.parse.
Proč výměna knihoven obvykle nepomůže?
JSON.parse je už nativní a rychlý; většina „pomalého parsování“ pochází z opakovaného parsování nebo vykreslování desítek tisíc uzlů najednou. Výměna knihovny přinese 10–30 %, zatímco odstranění jednoho celého parsování často ušetří polovinu.
Mám přesunout parsování do Web Workeru?
Přesuňte ho do workeru, když parsování blokuje hlavní vlákno a stránka zamrzne nebo animace ztrácejí snímky. Předejte surový text, nikoli parsovaný objekt, jinak strukturované klonování v postMessage zdvojnásobí náklady.