JSON Toolkit

Tệp JSON lớn không mở được: chọn đúng công cụ theo dung lượng

Kết luận: Các tệp xuất JSON hàng chục MB thường khiến trình soạn thảo văn bản và công cụ trực tuyến bị treo, trong khi việc phân tích chỉ mất vài trăm mili giây. Chúng tôi đo thời gian và bộ nhớ ở từng giai đoạn trên mẫu 45 MB với 500.000 bản ghi, chỉ ra chi phí thực nằm ở số dòng và số nút, và đưa ra bảng chọn công cụ theo dung lượng: xem trực tuyến, dòng lệnh, xử lý luồng và ứng dụng desktop.

Trung cấpĐọc khoảng 6 phútXuất bản 2026-11-07Cập nhật 2026-11-07
Bậc thang chọn công cụ cho JSON lớn theo dung lượng: trực tuyến, CLI, luồng

Tệp JSON 45 MB phân tích chỉ trong 249 mili giây. Nửa phút chờ đợi đến từ việc hiển thị năm triệu dòng văn bản và 3,5 triệu nút cây. Nhầm lẫn hai điều này, bạn sẽ đổ lỗi cho sai đối tượng mỗi lần.

Một: đo trước — phân tích không bao giờ là nút cổ chai

Nhấp đúp vào tệp xuất .json hàng chục MB, trình soạn thảo quay vòng ba mươi giây, và phản xạ nói rằng "phân tích JSON chậm". Số liệu đo cho thấy điều ngược lại. Trên máy của chúng tôi (Node 22), chúng tôi tạo mẫu 500.000 bản ghi, mỗi bản năm trường (id, email, active, score, tags), 45 MB ở dạng nén gọn:

Thao tác Kết quả đo
JSON.parse toàn bộ 249 ms
JSON.stringify(data, null, 2) — đầu ra định dạng đẹp 215 ms
Văn bản sau định dạng 71 MB, 5.000.001 dòng
Tổng số nút cây (bản ghi + trường) khoảng 3.500.001
RSS tiến trình Node sau phân tích 313 MB (gấp khoảng 7 lần dung lượng tệp)

Phân tích kết thúc trong một phần tư giây. Trình phân tích làm xong việc trước khi bạn thả chuột. Mọi giây sau đó đều trôi qua ở tầng "hiển thị kết quả cho con người": trình soạn thảo phải dàn năm triệu dòng, tô sáng cú pháp từng dòng và giữ bộ đệm hoàn tác; trình xem cây phải tạo phần tử DOM cho từng nút trong 3,5 triệu nút — và các trình duyệt vấp ở khoảng một trăm nghìn nút, mất phản hồi lâu trước một triệu.

Kết luận chỉ theo hướng hoàn toàn khác: đừng chiến đấu với việc hiển thị — hãy dùng công cụ không hiển thị tất cả cùng lúc.

Hai: vì sao treo — số dòng và số nút mới là chi phí thực

Dung lượng tệp chỉ là bề nổi. Hai con số phái sinh làm gãy công cụ:

  1. Số dòng. JSON nén gọn 45 MB sau khi định dạng đẹp thành năm triệu dòng. Dù bạn xem phần nào, trình soạn thảo phải dựng trước cấu trúc dòng của toàn bộ tệp, xử lý trạng thái tô sáng và cấp phát bộ đệm — chi phí tỷ lệ thuận với tổng số dòng.
  2. Số nút. Nửa triệu bản ghi × (một đối tượng + năm trường) là 3,5 triệu nút. Bất kỳ trình xem nào dựng toàn bộ cây trước khi hiển thị đều trả cùng một bộ nhớ và thời gian — bạn mở một nhánh hay mở hết cũng vậy.

Từ đó có hai hệ quả trái trực giác. Định dạng đẹp trước khi xem là tự hại — tệp phình từ 45 lên 71 MB, số dòng nhân bốn mươi, thêm áp lực thuần túy cho công cụ. Đẩy tệp qua cat vào terminal cũng tự hại — bộ đệm cuộn trở thành nút cổ chai mới; muốn xem vài trăm byte đầu, head -c 2000 là đủ.

Ba: chọn công cụ theo dung lượng — bảng quyết định

Dung lượng khác nhau đòi công cụ hoàn toàn khác nhau. Kết hợp số liệu đo trên với các hướng dẫn công khai (OpenFormatter đặt vùng thoải mái của công cụ trực tuyến ở 2-5 MB; PureJSON ước tính bộ nhớ sau khi phân tích tài liệu 500 MB vào khoảng 2-4 GB), ta có bảng sau:

Dung lượng tệp Lựa chọn đầu Vì sao
< 2 MB Công cụ trực tuyến nào cũng được Xem ngay lập tức; xem cây + kiểm tra hợp lệ kiểu /parse một bước
2 – 20 MB Trình soạn thảo cục bộ (VS Code) hoặc công cụ cục bộ trong trình duyệt Công cụ trực tuyến bắt đầu xấu đi; xử lý cục bộ không gửi đi đâu
20 – 100 MB Thám sát bằng jq trên CLI + trình xem cây ảo hóa Trình soạn thảo bắt đầu giật; jq rút ra bất kỳ đoạn nào trong vài giây
100 MB – 1 GB jq --stream / ijson, xử lý luồng Bộ nhớ phân tích thông thường tăng tới ~7 lần dung lượng tệp; không chứa nổi thì dùng luồng
> 1 GB hoặc ghi thêm liên tục Đổi định dạng: NDJSON / CSV / Parquet Một mảng khổng lồ phải phân tích trọn vẹn mới dùng được bản ghi đầu tiên; vấn đề nằm ở chính định dạng

Công cụ /parse của trang này phủ bậc đầu tiên: xem cây và kiểm tra hợp lệ. Tệp lớn hơn nên dùng ứng dụng desktop, để hàng chục MB không bao giờ được dán vào trang web.

Bốn: đừng mở tệp — hãy hỏi cấu trúc trước

Đối diện tệp JSON lớn lạ hoắt, động tác đầu tiên không phải là mở, mà là dành vài giây tìm hiểu hình dạng. jq trả lời ba câu hỏi trong khoảng 200 ms:

# Ở trên cùng là mảng hay đối tượng? Có bao nhiêu bản ghi?
jq 'if type == "array" then {type: "array", count: length} else {type: "object", keys: (keys|length)} end' huge.json

# Bản ghi đầu tiên trông thế nào (một bản, không loàng loàng)?
jq '.[0]' huge.json | head -40

# Tên tất cả các trường (lấy từ bản ghi đầu tiên)
jq '.[0] | keys' huge.json

Khi đã biết cấu trúc, phần lớn yêu cầu thu về "rút một trường" — chẳng cần mở tệp. Ví dụ, muốn lấy email của mọi người dùng:

jq -r '.[].email' huge.json | less
# Chồng thêm bộ lọc
jq -r '.[] | select(.active == true) | .email' huge.json

Quy tắc đơn giản: để "xem", dùng trình xem có kết xuất ảo hóa; để "tìm và rút", dùng jq. Đừng trộn hai vai trò trong một công cụ.

Năm: vách bộ nhớ — chế độ thường so với luồng, chênh 150 lần

Trên cùng mẫu 45 MB, /usr/bin/time -v đo bộ nhớ đỉnh của jq ở hai chế độ:

Chế độ Lệnh Bộ nhớ đỉnh (RSS) Thời gian
Thường (tải toàn bộ) jq '.[0].email' sample.json 542 MB 0,7 s
Luồng jq --stream 'select(.[0][1]=="email") | .[1]' sample.json 3,6 MB 2,5 s

Chế độ thường đọc cả tệp và dựng đồ thị đối tượng; đỉnh 542 MB xác nhận quy tắc "đồ thị đối tượng ≈ 7-12 lần dung lượng văn bản". --stream tiêu thụ đầu vào từng token, giữ bộ nhớ ở mức vài MB — đổi lại tổng thời gian lâu hơn. Quá mốc gigabyte, chênh lệch này tách "chạy được" khỏi "bị OOM killer giết":

# Cho tệp lớn hơn bộ nhớ: --stream là chế độ duy nhất không bao giờ tải hết
jq --stream -n 'fromstream(1|truncate_stream(inputs))' huge.json

Tương đương bên Python là ijson: ijson.items(f, 'item') đưa ra phần tử mảng từng cái một với cùng bộ nhớ hằng. Giá chung của những công cụ này là từ bỏ truy cập ngẫu nhiên — luồng chỉ là một lượt đi xuôi, lượt thứ hai nghĩa là đọc lại tệp.

Sáu: trình duyệt đi được đến đâu — giới hạn của xử lý cục bộ

Công cụ trực tuyến dùng được, trong giới hạn. Một tab trình duyệt hiện đại có khoảng 1-4 GB bộ nhớ; tệp 45 MB phân tích thành đồ thị cộng cây thường trụ nổi. Vài trăm MB đã gần vách đá. Khi chọn trình xem trực tuyến, đòi hỏi ba điều:

  1. Xử lý diễn ra cục bộ (nội dung dán vào không bao giờ gửi tới máy chủ) — vừa bảo vệ dữ liệu vừa tiết kiệm thời gian tải lên; mọi công cụ trên trang này chạy trọn trong trình duyệt và dùng được offline;
  2. Phân tích chạy trong Web Worker — luồng chính không đóng băng, treo chỉ tốn một tab chứ không phải cả trình duyệt;
  3. Cây được ảo hóa hoặc mở lười — nhánh gập gần như không tốn gì, chỉ phần nào mở mới được kết xuất.

Trên trang này: /parse phù hợp thám sát cấu trúc và định vị lỗi với tệp tới vài chục MB; hơn thế thì jq hoặc ứng dụng desktop, trình duyệt chỉ giữ cho các mẩu nhỏ.

Bảy: chọn đúng định dạng, nửa số vấn đề tan biến

Nếu bạn chi phối cách tệp được tạo ra, trình xem tốt hơn là cách chữa sai — hãy khiến nó không lớn dần thành "một mảng khổng lồ duy nhất":

  • NDJSON/JSONL: mỗi dòng một bản ghi. Ghi thêm không chép lại tệp, head, grep, tail, split dùng thẳng; tệp bị cắt mất mỗi dòng cuối. Sổ tay JSONL của chúng tôi có quy trình đầy đủ để xử lý dòng hỏng.
  • Xuất có phân trang: API trả 100.000 bản ghi nên nhận tham số phân trang — mỗi lần 100 bản thuận cả hai phía.
  • Dạng bảng thì đừng dùng JSON: mỗi dòng một bản ghi, trường cố định không lồng nhau — đó là bảng. CSV hoặc Parquet nhỏ hơn và hệ sinh thái giàu hơn.

Con số đáng nhớ: cắt đôi mảng 500.000 bản ghi, nửa đầu vẫn là tệp NDJSON hợp lệ (một nửa bản ghi sống sót), còn mảng khổng lồ tương ứng mất trắng. Cứu được 500 trên 501 bản ghi vẫn hơn con số không.

Tám: checklist

  • Thám sát cấu trúc trước bằng jq '.[0] | keys' hoặc mẫu 500 bản ghi;
  • Không bao giờ định dạng đẹp chỉ để mở tệp — gấp đôi số dòng chỉ làm chậm thêm;
  • Dưới 2 MB: xem cây trực tuyến; trên 20 MB: dòng lệnh; trên 1 GB: luôn dùng --stream hoặc ijson;
  • Xác nhận công cụ trực tuyến xử lý cục bộ (nội dung dán không rời trình duyệt);
  • Nếu bạn kiểm soát phần tạo tệp, chuyển sang NDJSON hoặc phân trang để tiêu diệt mảng khổng lồ từ gốc.

FAQ

Vì sao trình soạn thảo mở JSON hàng chục giây trong khi chương trình phân tích chỉ 200 ms?

Phân tích là mã gốc biến văn bản thành cấu trúc dữ liệu: 249 ms với mẫu 45 MB. Trình soạn thảo vấp ở phần trình bày: năm triệu dòng để dàn, tô sáng và giữ bộ đệm hoàn tác; cây dựng DOM cho 3,5 triệu nút. Trình xem ảo hóa hoặc rút trực tiếp bằng jq né được tất cả.

jq có tràn bộ nhớ với JSON trên 1 GB không?

Ở chế độ thường thì có: nó tải cả tài liệu, đồ thị đối tượng đạt đỉnh 7-12 lần dung lượng tệp. Với --stream, đầu vào được tiêu thụ từng token: thử nghiệm 45 MB của chúng tôi đạt đỉnh 3,6 MB, và bộ nhớ phẳng bất kể kích thước tệp — đổi lại chỉ một lượt duyệt tuần tự.

Công cụ JSON trực tuyến chịu được tệp cỡ nào?

Phần lớn thoải mái tới 2-5 MB và xấu đi rõ sau 10 MB. Trần cứng là bộ nhớ tab (khoảng 1-4 GB), nhưng tới vài chục MB đã đau vì chờ phân tích và dựng cây. Quá 20 MB, chuyển sang công cụ cục bộ hoặc dòng lệnh.

Làm sao xem giá trị một trường trong JSON khổng lồ?

Rút bằng jq thay vì mở tệp: jq -r '.[].email' huge.json in ra mọi email; có bộ lọc thì jq -r '.[] | select(.active == true) | .email'. Xem vài bản đầu: jq '.[0:5]' huge.json — nhanh hơn mở tệp nhiều bậc.

Định dạng đẹp trước khi mở có giúp gì không?

Không. Định dạng đẹp biến 45 MB nén gọn thành 71 MB và một dòng thành năm triệu, chỉ thêm gánh nặng thuần túy cho trình soạn thảo và trình xem. Hãy dành việc định dạng đẹp cho thứ con người sẽ đọc — và chỉ khi tệp đủ nhỏ.