- Webブラウザが効率的に 遅延読み込み(lazy-loading) できる 単一HTMLアーカイブファイル形式 で、すべてのアセットを含みつつ、静的・単一・効率性を同時に実現
- HTMLとJavaScriptヘッダーの後ろに tarball形式の元のHTMLとアセット を結合し、JSがHTTP Rangeリクエストを通じて必要な部分だけを読み込む構造
- 既存の SingleFile や MHTML などは静的性と単一性は備えるが効率性が不足しており、Gwtarはこれを解決
- サーバー側の追加設定なしで 標準ブラウザ機能だけで動作 し、Cloudflareなど一部環境ではMIMEタイプ
x-gwtar で対応
- 大容量HTMLページの 保存性とアクセシビリティ を同時に確保し、長期Webアーカイブおよび再現可能な研究資料の保管に有用
Gwtar 概要
- Gwtarは 単一HTMLファイル で構成された新しい ポリグロット(Polyglot)アーカイブ形式 で、ブラウザがHTTP Rangeリクエストを通じて必要な部分だけを読み込む
- Gwern.netの大規模HTMLアーカイブ提供に使用
- HTMLヘッダーのJSがファイル全体のダウンロードを中断し、必要なアセットだけを 部分リクエスト(range request) で読み込む
- 結果としてサーバーは単一のHTMLファイルだけを提供するが、ユーザーは必要なアセットだけをダウンロードする
- すべての機能が標準ブラウザ機能で実装されており、将来互換性 を確保
HTMLアーカイブの三重ジレンマ
- HTMLアーカイブには 静的性、単一ファイル性、効率性 のうち2つしか満たせない既存の限界が存在
- 例: SingleFileは静的・単一だが非効率、WARCは静的・効率的だが単一ファイルではない
- SingleFileで生成されたスナップショットは完全な静的ページを提供するが、すべてのアセットをBase64でインライン化 するため、ファイルサイズが数百MBに大きくなる
- ユーザーはページの一部しか見なくてもファイル全体をダウンロードしなければならないという非効率が生じる
- Gwern.netはこれを解決するため deconstruct_singlefile.php でアセットを分離したが、単一ファイル性を失った
Gwtarの技術的アプローチ
- HTTP Rangeリクエストを活用して ファイルの一部だけを選択的にダウンロード 可能
- HTML + JSヘッダーの後ろにtarballを結合した 連結(concatenated)アーカイブ構造 を採用
- JSの
window.stop() コマンドでヘッダー以降のダウンロードを中断し、必要なアセットだけをリクエスト
- ブラウザは通常のHTMLのようにレンダリングし、JSがアセットリクエストを横取りしてRangeリクエストに変換
生成と実装
- PHPスクリプト deconstruct_singlefile.php によりSingleFile HTMLをGwtarへ変換可能
- JPG/PNG/GIFの再圧縮および PAR2 FEC(前方誤り訂正) データの追加をサポート
- ブラウザはJS実行後、必要なアセットだけをRangeリクエストで読み込み、JS無効時にはファイル全体のダウンロードに置き換わる
- 標準ベースのため サーバー設定や追加ソフトウェアは不要 で、単一ファイルから再び複数ファイルのHTMLへ復元可能
性能と互換性
- Rangeリクエスト非対応時はファイル全体をダウンロードするが、gzip/Brotli圧縮 により速度を補完可能
- Cloudflareは
text/html 応答のRangeヘッダーを削除するため、Gwern.netはMIMEタイプを x-gwtar に設定して回避
- ローカルではファイルを閲覧できない :
- これはSingleFileZも同様で、ブラウザのセキュリティポリシー(CORSなど)によりJSリクエストがブロックされるため
- 残念だが 許容可能なトレードオフ と考えられており、ローカル閲覧はJS依存ではないファイルへの変換で解決可能
拡張機能
- Gwtarファイル末尾に 追加のバイナリデータ(例: FEC、署名、メタデータ)を付加可能
- PAR2を利用してファイルの一部が破損した場合でも復旧可能
- GPG署名をHTMLコメント形式で挿入し、完全性検証 が可能
- 将来のバージョンでは アセットのハッシュ検証、自動プリフェッチ、圧縮内蔵、複数ページ対応 などを計画
活用可能性
- 大規模HTMLページや 研究データセット(例: SQLite3) を含む再現可能な科学研究に適している
- ブラウザで直接データベースをRangeリクエストで読み込み、分析可能
- 長期保存性とアクセシビリティを同時に確保する Webアーカイブ形式 として提案されている
ライセンスと今後の開発
- Gwtarの文書とコードは CC-0パブリックドメイン として公開
- 今後のバージョン(v2)では FEC義務化、内蔵圧縮、複数文書対応、重複除去改善 などが検討されている
1件のコメント
Hacker Newsのコメント
今日初めて window.stop() を知った
この関数は、ブラウザがそれ以上リソースを読み込まないように停止させる機能を持つ
主要ブラウザではすでに10年以上サポートされている (MDNドキュメント, Can I Use)
使用例はこのスクリーンショットで見られる
詳しくは私のブログ記事にまとめてある
ただし、サーバー中心のロジックでダウンロードや lazy-loading を自前で実装しようとする場合には、興味深いアプローチかもしれない
初期化やリダイレクトスクリプトのような特殊な状況でなければ、あまり推奨はしにくい
私は自作のバンドラーを通じて、ファイルを圧縮済み base64 チャンクの形で公開していて、方式としてはこれに近い
もしこうした単一ファイル共有環境で動くなら、プラットフォーム側がこれを塞ぐかもしれないとも思う
PHP にも似た __halt_compiler() という機能があり、ファイル末尾にドキュメントやデータをコメントなしで入れるときに使ったことがある
最初は面白いと思ったが、この形式が ローカルファイル から直接開けないと知ってためらった
アーカイブ用フォーマットなら、ローカルアクセスは主要なユースケースの一つのはずだ
しかしローカルで直接開けないなら、その利点はかなり薄れる (backdoor pilot の概念を参照)
画像、CSS、JS はすべて data-uri でインライン化でき、フォントも同様だ
むしろワードプロセッサの文書フォーマットが HTML を使っていれば、もっと柔軟だったかもしれない
python -m http.serverのようなコマンドでローカルサーバーを立てれば簡単に解決できるClaude コマンドでも可能だ
著者がこれを見ているなら、アーカイブフォーマットに BASE64 スクリーンショットフィールド と 説明フィールド、さらに ISO タイムスタンプ を追加してほしい
さらに、同じ URL の複数バージョンを保存できて、重複アセット除去 機能があれば理想的だと思う
筆者が WARC を否定的に見ている理由がわからない
むしろ Gwtar のほうが複雑で柔軟性に欠けるように見える
SingleFileの ZIP/HTML polyglot フォーマットが「静的で単一だが非効率的」だとされた理由が気になる
Gwtar と比べてどこが非効率なのか知りたい
ブラウザが要求したときにファイル全体を取得せず、range request で必要な部分だけを取れるかどうかが核心だ
本当にすばらしいアイデアだ
私は 単一ファイル HTML ウェブアプリ が、最も長く持続可能なソフトウェア形態だと考えている
私が作った例としては FuzzyGraph と HyperVault がある
私も似たようなものを Service Worker レベルで実装してみようかと考えたことがある
ページ自体はそのままにして、すべての HTTP リクエストを横取りする方式だ
window.stop() のように HTML の一部だけを受け取り、残りをアセットの blob として扱う構造になる
Service Worker 自体を dataURI に入れれば、完全な単一ファイルにもできる
興味深いが、ローカルファイルで lazy load がなぜ必要なのかはいまひとつわからない
そんなに大きなファイルを想定しているのか? それとも、既存の実装をそのまま維持したいのか?
ネットワーク越しに全体を受け取らず、必要な部分だけを要求するために range request が必要になる
もちろん複数ファイルに分けるほうが一般的だが、単一ファイル管理のほうが便利なこともある
おそらく Gwern の MediaWiki ベースのサイト 構造とも関係しているのだろう
以前、私も似たようなものを作ったことがある — Zundler というプロジェクトで、かなり ハッキーなアプローチ だった
ローカルでも動くが、最初に全体を展開しなければならない
ただし、セキュリティ制限 をどう回避しているのか気になる
説明では単一オリジン (single-origin) への言及しかなく、完全には理解できなかった