JSON Toolkit

Mempercepatkan penghuraian JSON besar

Inti pati: Mengoptimumkan dalam urutan yang salah menjadikan setiap pertukaran pustaka tidak berguna. Ukur rangkaian, huraian dan render secara berasingan, kemudian kurangkan huraian, kecilkan muatan dan strim.

Pertengahan~5 min bacaanDiterbitkan 2026-10-30Dikemas kini 2026-10-30
Urutan untuk mengoptimumkan penghuraian JSON besar

Pokoknya: ukur rangkaian, huraian dan render secara berasingan dahulu — kebanyakan "penghuraian lambat" sebenarnya render lambat — kemudian naik tangga mengikut urutan: lebih sedikit huraian, muatan lebih kecil, strim, worker, dan format binari terakhir.

Jangan mula dengan menukar pustaka. Tambah satu pemasa dan anda biasanya akan mendapati render itulah masalahnya.

Langkah satu: ukur peringkat

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();
Peringkat dominan Masalah sebenar Pembetulan
Rangkaian Muatan terlalu besar Pemilihan medan, penomboran halaman, pemampatan
JSON.parse Input benar-benar besar Lebih sedikit huraian, strim, worker
Render Puluhan ribu nod serentak Senarai maya, penomboran, kawalan kembang

Pelayar moden menghuraikan 1MB dalam kira-kira 5–15ms dan 10MB dalam 80–150ms. Jika 10MB mengambil dua saat, JSON.parse bukanlah kesesakan anda.

Langkah dua: huraikan lebih sedikit

Kemenangan paling murah, dan paling terlepas pandang.

  • Hentikan penghuraian muatan yang sama berulang kali. Sepuluh komponen yang masing-masing memanggil JSON.parse(localStorage.getItem(...)) ialah sepuluh penghuraian. Cache sekali pada peringkat modul.
  • Hentikan penggunaan JSON.parse(JSON.stringify(x)) untuk salinan dalam. Ia berharga lebih daripada dua kali jumlah data; structuredClone tidak.
  • Jangan huraikan pada utas utama dan kemudian hantar objek itu kepada worker. postMessage mengklonnya sekali lagi. Hantar teks mentah dan biarkan worker menghuraikannya.
  • Minta lebih sedikit medan. Jika UI memerlukan tiga sifat, API tidak sepatutnya menghantar tiga ratus.

Langkah tiga: kecilkan muatan

Penomboran halaman mengikut page/size, kursor dan bukannya offset dalam, medan ringkasan dalam titik akhir senarai. Ini biasanya mengalahkan setiap pengoptimuman frontend digabungkan, kerana ia mengurangkan rangkaian, huraian dan memori serentak.

Langkah empat: strim

Apabila data mesti diproses secara keseluruhan dan benar-benar besar:

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);
}

Lebih banyak kod, dan tiada akses rawak — hanya sesuai untuk pemprosesan rekod demi rekod.

Langkah lima: pindahkan daripada utas utama

Penghuraian pantas tetapi menyekat. Letakkannya dalam worker dan hantar teks, bukan objek yang dihuraikan, atau pengklonan berstruktur menggandakan kos.

Langkah enam: tukar format, terakhir

Untuk trafik dalaman yang secara konsisten berpuluh megabait, NDJSON mengalir secara semula jadi, dan Protobuf atau MessagePack lebih kecil dan lebih pantas. Kedua-duanya ialah perubahan protokol yang memerlukan penyelarasan.

Jangan

  • eval JSON: tidak selamat dan tidak lebih pantas
  • Menjadikan JSON sebagai rentetan untuk membenamkannya dalam JSON: menggandakan saiz
  • Huraikan ratusan ribu rentetan kecil dalam gelung: kelompokkan

Soalan Lazim

Bagaimana saya tahu sama ada penghuraian atau render ialah kesesakan?

Masa permintaan, bacaan teks, JSON.parse dan render secara berasingan dengan performance.now(), dan anggap peringkat terbesar sebagai kesesakan sebenar. Pelayar moden menghuraikan 1MB dalam kira-kira 5–15ms dan 10MB dalam 80–150ms, jadi muatan 10MB yang mengambil dua saat jarang merupakan masalah JSON.parse.

Mengapa menukar pustaka biasanya tidak membantu?

JSON.parse sudah asli dan pantas; kebanyakan "penghuraian lambat" datang daripada penghuraian berulang atau render puluhan ribu nod serentak. Pertukaran pustaka membeli 10–30%, manakala membuang satu penghuraian penuh selalunya menjimatkan separuh.

Patutkah saya memindahkan penghuraian ke Web Worker?

Pindahkan ke worker apabila penghuraian menyekat utas utama dan halaman tersekat atau animasi tercicir bingkai. Hantar teks mentah dan bukan objek yang dihuraikan, jika tidak pengklonan berstruktur postMessage menggandakan kos.

Bacaan lanjut