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.

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;structuredClonetidak. - Jangan huraikan pada utas utama dan kemudian hantar objek itu kepada worker.
postMessagemengklonnya 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
evalJSON: 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.