JSONビューアー
JSONビューアーは、ドキュメントをブラウザ内で折りたたみ可能なツリーとして表示します。ツリーはフラット化した行リストの上に仮想化されているため、5万ノードのAPIレスポンスでも小さなドキュメントと同じ速度で開き、スクロールできます。また、各行にはそのノードを指すRFC 6901ポインタが付いています。
JSONビューアーはどう動きますか?
JSONビューアーの評価は、テキストとして読むには大きすぎるドキュメントでの挙動ひとつで決まります——それこそが、誰もがビューアーを開く唯一の理由です。大半のビューアーはここで失敗しますが、その理由は構造上どこも同じです。ツリーを、ノード1個につき1つのネストしたコンポーネントとして描画しているのです。この素朴な実装では、5万ノードのレスポンスが5万個のDOM要素を生み出し、画面に表示されているのはおそらく40個ほどです。スクロールはカクつき、ブランチを展開するとサブツリー全体が再描画され、タブは数百メガバイトを消費し始めます。
このビューアーは、まずドキュメントを行の配列にフラット化します。各行には、深さ、型、子の数、そしてそのサブツリーが終わるインデックスを持たせます。そのうえで、ビューポート内の行だけを描画します。DOMが保持するのはドキュメントのサイズに関係なく50要素ほどなので、大きなファイルも小さなファイルと同じ速さで開きます。
各サブツリーの終端位置を記録していることが、折りたたみを安価にしています。ブランチを隠すのは、中身をすべてたどるのではなく、インデックスを1回スキップするだけです。50,000ノードのドキュメントのルートを折りたたむコストは、5万回ではなく比較1回です。同じ構造のおかげで検索も合理的になります。一致は、展開されている部分だけではなくドキュメント全体から見つかり、一致に至るパス上の祖先はすべて保持されます。パスのない値は何も教えてくれないからです。
フラット化は、再帰ではなく明示的なスタックによる反復処理です。再帰でたどると、1万階層前後のネストでJavaScriptのコールスタックがオーバーフローします。そこまで深いドキュメントこそ、他の何も開いてくれないためにビューアーに持ち込まれるドキュメントです。2万階層のテストもあります。
各行には、そのノードを指すRFC 6901 JSONポインタ——/order/lines/0/sku——が表示され、クリックするとコピーできます。JSON Patchのオペレーション、jqのパス、テストのアサーション、バグ報告に貼り付けるのがまさにこの文字列です。正確な形で手に入ることで、見慣れないレスポンスを扱う作業の中で最も面倒な一手間がなくなります。
ドキュメント
{"order":{"lines":[{"sku":"WID-1","qty":2}]}}ツリー
▾ root { 1 }
▾ order { 1 }
▾ lines [ 1 ]
▾ 0 { 2 }
sku "WID-1" /order/lines/0/sku
qty 2 /order/lines/0/qtyJSONビューアーが対応するオプションとエッジケースは?
| パラメータ | 型 | デフォルト | 動作とエッジケース |
|---|---|---|---|
| 初期の深さ | 階層 | 2 | この深さを超えるコンテナは折りたたまれた状態で開始され、大きなドキュメントが4万行ではなく読みやすい概要として開かれます。「すべて展開」は1回のクリックです。 |
| 仮想化 | 表示範囲のみ | — | ドキュメントのサイズに関係なく、常にDOMに約50行が存在します。これにより、20MBのレスポンスを開くビューアーと、タブがフリーズしてしまうビューアーの違いが生まれます。 |
| 検索 | 部分一致 | 大文字小文字を区別しない | キーとレンダリングされた値を、折りたたまれたブランチを含むドキュ全体で検索し、一致した項目のすべての祖先を保持してパスが表示されたままになるようにします。 |
| JSONポインタ | RFC 6901 | 行ごとに表示 | クリックしてコピーします。/や~を含むキーは~1と~0にエスケープされるため、ポインタは単に一見正しいだけでなく正確になります。 |
| タイプの色分け | 文字列、数値、真偽値、null | — | スカラーは型によって色分けされ、数値の文字列"42"と数値の42は視覚的に区別されます——この区別は、驚くほど多くの統合バグの原因となります。 |
| 編集 | 非対応 | — | これはビューアーです。値の編集、キーの名前の変更、配列の並べ替えには、テキストペインとツリーを同期させるJSONエディタを使用してください。 |
| 入力サイズ | bytes | 8 MB | パーサーはメインスレッドで実行されます。上限を超えると、ツールはフリーズするのではなく処理を拒否します。ツリー自体は、パーサーの上限が許すよりもはるかに多くのノードを処理できます。 |
よくある質問
本当に大きなファイルも開けますか?
8 MBのパース上限までは開けます。ツリーはボトルネックではありません——画面に表示される分だけを描画するため、ノード数の影響はほとんど受けません。限界になるのはパースの工程で、これはメインスレッドで実行されるため、8 MBを超える入力には挑戦せずに拒否します。挑んだらタブが固まってしまうからです。
各行の横にある/order/lines/0/skuは何ですか?
そのノードを指すRFC 6901 JSONポインタです。クリックするとコピーできます。JSON Patchのオペレーション、テストのアサーション、バグ報告に貼り付けるパスであり、正確な形で手に入ること——~や/を含むキーのための~0と~1のエスケープを含めて——が、「どこにあるか」を記述する作業の中で最もミスしやすい部分を取り除きます。
ここで値を編集できますか?
意図的にできません。編集も兼ねたビューアーは、キーストロークのたびに2つの真実の源を突き合わせなければなりません。だからこそJSONエディターは別のツールです。テキストペインとツリーをアンドゥ付きで同期させています。このツールを読み取り専用に保っているからこそ、エディタでは苦労するようなドキュメントでも速さを維持できるのです。
数値が文字列と違う色で表示されるのはなぜですか?
スカラーは型ごとに色分けされます。思った以上に重要です。文字列\"42\"と数値42は、生のテキストでは同じ見た目ですが、その後の処理ではまったく異なる振る舞いをします。整数が期待される場所にクォートされた文字列が来るのは、連携の失敗として繰り返し現れる原因であり、色分けはそれを一目で見えるようにします。
検索は折りたたまれたブランチの中も見てくれますか?
はい。検索は表示中の行ではなく、フラット化したドキュメント全体を対象に実行されます。折りたたまれたサブツリーの中に埋もれた一致も見つかり、そこに至る祖先とともに表示されます。クエリを消すと、ツリーは展開していた元の状態に戻ります。
ドキュメントはアップロードされますか?
いいえ。すでに開いているタブの中で、JavaScriptがパースし、描画します。DevToolsを開いてNetworkパネルを表示し、レスポンスを貼り付けてみてください——それを運ぶ通信は何も出ていきません。ビューアーが必要になるドキュメントはたいてい本番環境のAPIレスポンスであり、まさに、読めるようにするために見知らぬサーバーを通してほしくない類のものです。