BigPipe

BigPipe技術を使用してページを送信し、コンテンツをチャンク単位でストリーミングすることで、ブラウザがページをより高速に表示できるようにします。

big_pipe
2 sites
9
drupal.org

概要

BigPipeは、Facebookが開発したページレンダリング技術で、体感的なページ読み込みパフォーマンスを劇的に向上させます。ページ全体がレンダリングされるまで待ってからブラウザに送信するのではなく、BigPipeはページコンテンツをチャンク単位でストリーミングします。

このモジュールは、まずページの静的な「スケルトン」(ヘッダー、ナビゲーション、フッターなど)を即座に送信し、動的コンテンツ(ユーザー固有のブロック、パーソナライズされたデータ、CSRFトークン)は非同期でレンダリングされ、準備ができ次第ストリーミングされます。これにより、ブラウザは静的コンテンツをすぐにレンダリング・表示し始め、動的プレースホルダーは徐々に置き換えられていきます。

BigPipeはDrupalのレンダーシステムおよびプレースホルダー戦略と自動的に統合されます。キャッシュ可能性メタデータに基づいてプレースホルダー化すべきコンテンツを識別し、JavaScript(JSが有効なブラウザ向け)またはサーバーサイドストリーミング(JS無効時のフォールバック)を使用してプレースホルダーを置き換えます。このモジュールは手動での設定を必要とせず、認証済みユーザーおよびセッションを持つ匿名ユーザーに対して自動的に有効になります。

Features

  • Transfer-Encoding: chunkedを使用してHTMLレスポンスをチャンク単位でストリーミングし、ブラウザがすぐにレンダリングを開始できるようにします
  • JavaScript検出の自動化とJS無効ストリーミングモードへのインテリジェントなフォールバック
  • Drupalの自動プレースホルダーシステムとシームレスに統合し、動的コンテンツを識別します
  • 2つのプレースホルダー戦略をサポート:JSプレースホルダー(ページ末尾でAJAXにより置換)とJS無効プレースホルダー(ストリーミング中にインラインで置換)
  • HTMLプレースホルダーとHTML属性値プレースホルダー(URL内のCSRFトークンなど)の両方を処理します
  • セッション対応キャッシングのためのsession.exists Cacheコンテキストを提供します
  • CDN/プロキシ互換性のための適切なHTTPヘッダー(Surrogate-Control、X-Accel-Buffering)を設定します
  • BigPipeと互換性のないルート(バッチ処理、モジュールインストール)の自動除外
  • drupalSettings内のプレースホルダーIDホワイトリストによるXSS保護

Use Cases

認証済みユーザーの体感パフォーマンス向上

認証済みユーザーがページを読み込むと、BigPipeはページスケルトンを即座に送信し、ユーザー固有のコンテンツ(パーソナライズされたブロック、ステータスメッセージなど)は徐々にレンダリングされストリーミングされます。ユーザーはページレイアウトを即座に確認でき、動的コンテンツは準備ができ次第表示されていきます。

ショッピングカートを持つECサイト

ショッピングカートを持つ匿名ユーザーにはセッションがあり、BigPipeの恩恵を受けられます。商品一覧やページ構造は即座に読み込まれ、カートウィジェットやパーソナライズされたおすすめはプレースホルダーが解決されるとストリーミングされます。

生成コストの高い動的コンテンツを含むページ

生成に時間がかかるコンテンツ(複雑なデータベースクエリ、外部APIコール)を含むページの場合、BigPipeによりキャッシュ可能な部分を即座に表示しながら、時間のかかる動的コンテンツは計算されストリーミングされます。

CSRFトークンの処理

CSRFトークンを持つフォームやリンクは、BigPipeのJS無効プレースホルダー戦略の恩恵を受けます。ページ構造は即座に送信され、CSRFトークンは生成されるとインラインでストリーミングされます。JavaScriptは不要です。

JS無効ユーザーへのプログレッシブエンハンスメント

BigPipeはJavaScriptが無効になっていることを自動検出し、JS無効ストリーミングモードにフォールバックします。このモードではページ配信中にプレースホルダーがインラインで置き換えられます。これにより、JavaScript有効なユーザーだけでなく、すべてのユーザーがストリーミングの恩恵を受けられます。

Tips

  • BigPipeは、コンテンツにキャッシュ可能性メタデータが適切にアノテーションされている場合に最も効果的に動作します。Render Arrayに適切な#cache contextsとtagsが含まれていることを確認してください。
  • プレースホルダー化すべき動的コンテンツには#lazy_builderを使用してください。これはBigPipeのストリーミングメカニズムとシームレスに統合されます。
  • php-fpmを使用するNGINXの場合、BigPipeは自動的に'X-Accel-Buffering: no'ヘッダーを設定します。他のプロキシでは追加の設定が必要な場合があります。
  • JavaScriptを無効にしてサイトをテストし、JS無効フォールバックが正しく動作することを確認してください。
  • BigPipeはストリーミングされたコンテンツのアセット(CSS/JS)依存関係を自動的に処理し、必要に応じてAJAXコマンド経由で新しいライブラリを読み込みます。
  • モジュールは'Surrogate-Control: no-store, content="BigPipe/1.0"'ヘッダーを設定し、エッジキャッシュにBigPipeレスポンスをキャッシュしないよう通知します。

Technical Details

Hooks 2
hook_help

hook_help()を実装し、モジュールのヘルプページでBigPipeの機能と設定不要である旨のヘルプテキストを提供します。

hook_page_attachments

hook_page_attachments()を実装し、JS無効検出メカニズムを追加します。セッションが存在しJS無効Cookieが設定されていない場合、Cookieを設定するために/big_pipe/no-jsにリダイレクトする<noscript>メタリフレッシュを追加します。Cookieが存在する場合は、JavaScriptを追加してそれを削除します(JSが利用可能であることを示します)。

Troubleshooting 5
BigPipeが動作していないようです - ページが一度に読み込まれます

以下を確認してください:1)ユーザーにアクティブなセッションがあること(BigPipeは認証済みユーザーまたはショッピングカートなどのセッションを持つ匿名ユーザーにのみ動作します)。2)ホスティング環境がChunked Transfer Encodingをサポートし、レスポンス全体をバッファリングしていないこと。3)リバースプロキシやCDNがレスポンスをバッファリングしていないか確認。4)ルートに'_no_big_pipe'オプションが設定されていないことを確認。

プレースホルダー置換時にJavaScriptエラーが発生します

これは最近のパッチで対処されました。モジュールの最新バージョンを使用していることを確認してください。この問題は、同じプレースホルダーがページ内に複数回出現し、複数回レンダリング・送信される場合に発生していました。

BigPipeがリダイレクトループを引き起こします

JS無効検出メカニズムはCookieとメタリフレッシュリダイレクトを使用します。リダイレクトループが発生している場合は、Cookieが正しく設定されているか確認してください。big_pipe_nojs Cookieは最初のJS無効検出リダイレクト時に設定され、その後のリダイレクトを防止するはずです。

コンテンツが一瞬表示された後、消えるか間違った内容が表示されます

ブラウザコンソールでJavaScriptエラーを確認してください。BigPipeのJavaScriptは、drupalSettings.bigPipePlaceholderIdsのホワイトリストに対してプレースホルダーIDを検証します。セキュリティ上の理由から、不明なプレースホルダーは無視されます。

特定のルートでプレースホルダーが置き換えられません

一部のルートはBigPipeから自動的に除外されます(バッチページ、モジュールインストール)。ルートに'_no_big_pipe'オプションが設定されているか確認してください。必要に応じて、routing.ymlでカスタムルートにこのオプションを追加できます。

Security Notes 4
  • BigPipeレスポンスは常にプライベートとしてマークされ、セッション固有のコンテンツを含むため、共有キャッシュにキャッシュされることはありません。
  • プレースホルダーIDはdrupalSettingsでホワイトリスト化されており、プレースホルダー置換メカニズムを介したXSS攻撃を防止します。
  • CSRFトークンはJS無効プレースホルダーを介して処理され、タイミング攻撃にさらされることなくセッションごとに適切に生成されることを保証します。
  • big_pipe_nojs CookieはhttpOnlyフラグなしで意図的に設定されており、JSが利用可能な場合にJavaScriptがそれを削除できるようにしています。