2 ポイント 投稿者 GN⁺ 2025-05-05 | 1件のコメント | WhatsAppで共有
  • HTMLだけでは、同じ要素を複数ページに含めるための include 機能がない
  • CSSはCSSを、JavaScriptはJSを読み込めるのに、HTMLはHTMLを取り込めないのはなぜかという疑問
  • この問題を解決するために、さまざまな JavaScript、テンプレート言語、静的サイトジェネレーター などが使われている
  • パフォーマンス、セキュリティ、レンダリング遅延、循環インクルードなどの複雑な問題 が導入の障壁になっている
  • 多くの開発者がHTMLに 純粋な宣言的 include 機能 を望んでいるが、まだWeb標準には反映されていない

HTMLにInclude機能がない理由への疑問

問題提起

  • index.htmlabout.htmlcontact.html など複数のページで 共通ヘッダー を繰り返し挿入しなければならない不便さがある
  • 開発者は 重複なく、一度定義したヘッダーを再利用 したいと考えている

すでに存在する代替手段

  • JavaScriptの fetch API で外部HTMLを読み込み、DOMに挿入する方法
  • サーバーサイドインクルード(SSI)、PHPの include、静的サイトジェネレーター、テンプレート言語などが解決策として存在する
  • <iframe><object> のようなHTML要素も使えるが、アクセシビリティ、パフォーマンス、スタイル分離の問題 により不適切
  • 結局のところ HTML自体にはシンプルなインクルード構文がない

なぜHTMLにはこの機能がないのか?

  • CSSとJSにはそれぞれ @importimport 構文があるが、HTMLには存在しない
  • Web標準は一般に開発者がよく使う機能を取り込んできたが、HTMLインクルードはそうならなかった
  • 挙げられている理由:
    • プリロードスキャナー の動作を妨げる可能性
    • 非同期読み込み時のレイアウトシフトやちらつきの問題
    • ネストまたは循環インクルード処理の複雑さ
    • Webホスティングのトラフィック増加への反発
    • セキュリティ上の問題(CORS、CSPなど)ドキュメント読み込みイベントのタイミング衝突
    • あるいは単に 優先度が低く、明確な提案がなかっただけかもしれない

関連する議論

  • GitHubのWHATWG issueスレッド #2791 で活発に議論されている
  • かつてChromeには HTML Imports が存在したが、他ブラウザーでサポートされなかったこともあり 廃止された
  • HTMX、Web Components、XSLT、SSI などの代替アプローチも共有されている

コミュニティの反応まとめ

  • HTMLの進化が 静的マークアップ中心 のまま維持され、ロジック的な機能を排除 するという思想がなお強い
  • この機能を望む人は多いが、標準化プロセスで声を上げにくい個人開発者 が大半
  • パフォーマンス、セキュリティ、レンダリング処理、循環防止など の複雑な設計課題を解決しない限り導入は難しいという分析もある
  • ある開発者は、単に HTMLは「結果」だけを担うべきだという考え方 のためにインクルード機能が欠けていると見ている

結論

  • HTMLには現在も 純粋な include 機能は存在せず、さまざまな外部ツールや言語で代替する必要がある
  • それでも多くの開発者は依然として シンプルなHTMLベースの再利用構造 を期待している

1件のコメント

 
GN⁺ 2025-05-05
Hacker Newsの意見
  • HTMLは歴史的にSGMLの応用であり、SGMLはinclude機能をサポートしていた。新しい「エンティティ」を定義し、「システム」エンティティを作成すれば、後で参照して置き換えることができた
    • SGMLの複雑さのためにHTMLを単純化しようとするさまざまな試みがあり、その過程でこうした機能は削除された
  • 90年代後半、この問題を解決しようとする取り組みがあった。Analog Science Fictionウェブサイトのウェブマスターとして、同じヘッダーとサイドバーを持つ多くの静的ページを作っていた。そこでApacheのサーバーサイドインクルード機能を見つけた。これは、DRY原則を知る前にそれを維持する方法だった
    • この問題は何度もさまざまな方法で解決されてきた。iframeで十分だと言う人に対して言えば、iframeはコンテンツに合わせて拡張されない。サーバーサイドの解決策にはサーバーが必要だ。なぜシンプルなクライアントサイドの方法がないのか? これは妥当な疑問だと思う
  • HTML Importsという機能提案があった。これはWeb Componentsの一部として作られた
    • HTML Importsは、別のHTMLドキュメントにHTMLドキュメントを含めて再利用する方法である
    • GoogleはBlinkで提案仕様を実装したが、他社はさまざまな理由で反対した。Mozillaは実装の複雑さやセキュリティ上の問題、ES6モジュールとの重複を懸念していた。ベンダーの支持が得られず、この提案は正式に中止された
  • Netscape 4にはinflow layersという機能があった
    • この機能の名称はtransclusionである。これはProject Xanaduの一部で、もともとハイパーテキストの重要な機能と見なされていた
    • MediaWikiはtransclusionを広範に利用している。時にはWikiこそがハイパーテキストの真の形のように感じられる
  • 適切なframeset(iframeではない)は、ずっと前にこうした機能を果たすように設計されていた。少なくとも自動拡張はうまく機能し、ユーザーがサイズを調整することもできた
    • フレームには多くの批判があったが、Java APIドキュメントのような有用なものにはうまく導入されていた
    • framesetがデザイナーに十分な柔軟性を提供できなかったために維持されなかったのだと思う。今日のモバイルではframesetはうまく機能しないだろう
  • 「Includes」機能はサーバーサイドと見なされ、ウェブブラウザの外部で処理される。HTMLはクライアントサイドであり、単なるマークアップ構文であってプログラミング言語ではない
    • この問題は解決済みの問題である。「Includes」の問題は、すべてのウェブデザイン学生がPHPを学ぶきっかけになるものだ。ほとんどのCMSでは「Includes」は「テンプレートパーツ」となり、ドキュメントで最初に説明される事項のひとつである
    • HTMLだけで「Includes」を使う必要はない。HTMLはプレゼンテーション形式であり、CSSやJSなしでは面白いことはできない
  • HTMLのinclude機能にはいくつかの問題がある
    • main.htmlがchild/include1.htmlを含み、child/include1.htmlがリンク src="include2.html" を持っている場合、ユーザーがそのリンクをクリックしたとき、どこへ行くべきなのか? 「include2.html」へ行けば、そのページには他のすべてが欠けていることになる。「main.html」へ行くなら、今度はinclude1.htmlではなくinclude2.htmlを使うとどう指定するのか?
    • 逆に、article1.html、article2.html、article3.htmlなどがそれぞれheader.html、footer.html、navi.htmlを含めることはできる。しかし、すべての記事にcomments.htmlを追加したいなら、すべての記事を編集しなければならず、結局はテンプレートに基づいて記事を生成することになり、ブラウザがincludeをサポートする必要はなくなる
    • ヘッダーがタイトルを知りたかったり、フッターが次へ/前へリンクを必要としたりするなら、この情報をinclude間で渡す方法が必要になり、結局はページ生成へ行き着いて、includeは解決策ではなくなる
    • HTMLのincludeは、ほとんどのユースケースに対して実質的に役に立たないだろう
  • WHATWGにはこの問題に関する公開イシューがある
    • HTMLのクライアントサイドinclude機能
  • HTMLにはinclude機能があったが、人気を失った
    • 実際の「include」という用語はXMLの機能であり、記事が求めているのはその機能である。HTMLには、XML以前から存在していた代替アプローチがあった。そのアプローチがフレームだった。フレームはXML includeより多くの機能を提供していたため、HTMLはその機能を得なかった。フレームは誤用、セキュリティ、アクセシビリティ、その他さまざまな問題のために人気を失った