RefreshLess
DrupalのサーバーレンダリングHTMLの上にJavaScriptベースのナビゲーションを重ね、プログレッシブエンハンスメントを維持しながらスムーズで高速なSPAライクなユーザー体験を提供します。
refreshless
概要
RefreshLessは、従来のDrupalサーバーレンダリングページを、プログレッシブエンハンスメントを犠牲にすることなく、スムーズでレスポンシブなシングルページアプリケーション(SPA)ライクな体験に変換します。Hotwire Turboライブラリ上に構築されており、ページナビゲーションとフォーム送信をインターセプトし、AJAXを介して新しいコンテンツを読み込み、読み込み済みのJavaScriptとCSSを保持しながらDOMをシームレスに更新します。
完全なクライアントサイドSPAとは異なり、RefreshLessはJavaScriptが失敗した場合に従来のページ読み込みへの完全なフォールバックを維持し、不安定なネットワーク環境でもサイトが機能し続けることを保証します。このアプローチはDrupalの既存のTwigテンプレート、アセットライブラリシステム、キャッシュ、セキュリティ機能を再利用し、別のフロントエンドを再実装する必要を排除します。
主要な機能には、ナビゲーション間のインテリジェントなスタイルシートとスクリプト管理、戻る/進むナビゲーションを即座に行うためのクライアントサイドページキャッシュ、CSSアニメーションまたはView Transitions APIによるオプションのページトランジション、遅延リンクプリロード、そしてDrupalのAJAXシステム、ダイアログ、コンテキストリンク、メディアライブラリとのシームレスな統合が含まれます。
Features
- リンククリックとフォーム送信をインターセプトし、fetch APIでコンテンツを読み込み、完全なページリロードなしでDOMを更新するJavaScriptベースのナビゲーション
- JavaScriptが失敗したり利用できない場合に従来のページ読み込みへ自動的にフォールバックするプログレッシブエンハンスメント
- ナビゲーション間で読み込み済みのCSSとJavaScriptライブラリを追跡し、必要な場合のみ新しいアセットを読み込むインテリジェントなアセット管理
- Turboを活用したクライアントサイドページキャッシュによる、戻る/進むナビゲーションの即時化と新しいコンテンツ取得中のプレビューレンダリング
- カスタマイズ可能なCSSアニメーションとView Transitions APIのサポートによるオプションのページトランジション
- IntersectionObserverを使用して、リンクがスクロールで表示されるとキャッシュにプリロードする遅延リンクプリロード
- Turboリロードシナリオ間でフラッシュメッセージを保持するデコレートされたメッセンジャーサービス
- AJAX、ダイアログ、コンテキストリンク、メディアライブラリ、ナビゲーションモジュール、テーブルセレクトを含むDrupal Core機能の互換性レイヤー
- ナビゲーション中のページ読み込み状態を表示するプログレスバーインジケーター
- 特定のリクエストに対してプログラム的にRefreshLessを無効化するキルスイッチサービス
- RefreshLessの状態に基づく条件付きレンダリングのためのCache Context
Use Cases
高速ナビゲーションが必要なコンテンツ重視のウェブサイト
RefreshLessは、ユーザーが頻繁にページ間を移動するコンテンツ豊富なDrupalサイトに最適です。完全なページリロードを排除することで、サーバーレンダリングコンテンツのSEOメリットを維持しながら、ナビゲーションが瞬時に感じられます。クライアントサイドキャッシュにより、戻る/進むナビゲーションが即座に行われます。
ミッションクリティカルなサイト向けのプログレッシブエンハンスメント
JavaScriptの可用性に関係なく確実に機能する必要があるウェブサイト(政府サイト、医療、ECチェックアウト)では、RefreshLessはJavaScriptが失敗した場合に自動的に従来のナビゲーションにフォールバックしながら、SPAライクなUXを提供します。これによりコア機能の100%の稼働時間を保証します。
高コストなJavaScript初期化を持つサイト
サイトが大規模なJavaScriptライブラリを読み込んだり、複雑な初期化ルーチンを持っている場合、RefreshLessはページ読み込みごとの再初期化コストを排除します。CSSとJavaScriptは新しいアセットが必要な場合のみ追加的に読み込まれます。
頻繁なナビゲーションを伴う管理インターフェース
Drupal管理インターフェースは、エディターがコンテンツ一覧、編集、設定ページ間を頻繁に移動するため、RefreshLessから大きな恩恵を受けます。Gin統合モジュールと組み合わせることで、管理ワークフローが顕著に高速化され、レスポンシブになります。
ページトランジションとアニメーションが必要なサイト
refreshless_transitionsサブモジュールを使用することで、サイトはCSSアニメーションやモダンなView Transitions APIでスムーズなページトランジションを実装でき、従来のURLベースのナビゲーションを維持しながらアプリライクな体験を作成できます。
モバイルファーストのウェブサイト
refreshless_preloaderサブモジュールは、ホバーベースのプリフェッチが機能しないモバイルユーザーに特に価値があります。ユーザーがスクロールして表示させるとリンクがプリロードされ、その後のナビゲーションが即座に行われます。
Tips
- すべてのRefreshLess JavaScriptは最適な読み込みのためにdefer属性を使用しています。カスタムJavaScriptも互換性のためにdeferを使用することを確認してください。
- Turboのdata-turbo-temporary属性と同様に、キャッシュすべきでない要素にはdata-refreshless-temporary属性を使用してください。
- Drupal behaviorsを書く際は、常に要素を元の状態に完全に復元するdetachコールバックを実装してください。異なるdetachシナリオを処理するためにtriggerパラメータを使用してください。
- 開発中はrefreshless_debugモジュールを有効にして、すべてのRefreshLessイベントがブラウザコンソールにログ出力されるのを確認してください。
- 遅延リンクプリロードでは、個々のリンクではなくコンテナ要素にdata-refreshless-lazy-preloadを追加してください。特定のリンクはdata-refreshless-lazy-preload="false"でオプトアウトできます。
- キルスイッチサービス(refreshless.kill_switch)を使用すると、特定のリクエストに対してプログラム的にRefreshLessを無効化できます - 独自の要件を持つページに便利です。
- RefreshLessはテーマ変更を自動的に処理し、完全なリロードをトリガーします。ユーザーが頻繁にテーマを切り替える場合は、これを念頭に置いてサイトを設計してください。
- ページトランジションオーバーレイのカスタムCSSプロパティにより、JavaScriptの変更なしでテーマを適用できます。テーマで--refreshless-page-transition-*プロパティをオーバーライドしてください。
- refreshless:before-renderイベントはPromiseでレンダリングを遅延できます - コンテンツが変更される前にカスタム終了アニメーションを実装するのに便利です。
- refreshless:drupal-settings-updateをリッスンしてdrupalSettingsの変更に反応してください。previous、new、mergedの設定オブジェクトが提供されます。
Technical Details
Troubleshooting 8
必要なすべてのDrupal Coreパッチが適用されているか確認してください。'composer install'を実行してパッチが適用されていることを確認してください。JavaScriptコンソールにエラーが表示されていないことを確認してください。refreshless_turboサブモジュールが有効になっていることを確認してください。
RefreshLessは現在BigPipeモジュールと互換性がありません。RefreshLessをインストールする前にBigPipeをアンインストールしてください。BigPipe互換性の進捗についてはissue #3519784を参照してください。
これはデコレートされたメッセンジャーサービスによって自動的に処理されます。メッセージがまだ消える場合は、refreshless_turboモジュールが有効でメッセンジャーサービスのデコレーションがアクティブであることを確認してください。
behaviorsに変更を完全にクリーンアップする適切なdetachコールバックがあることを確認してください。@drupal/onceライブラリのonce()とonce.remove()を使用してください。behaviorコールバックの外にDOM要素参照を保存しないでください。
RefreshLessはCSS詳細度を維持するためにスタイルシートの順序を維持します。問題が続く場合は、refreshless:stylesheets-mergedイベントをリッスンし、必要に応じてrefreshless:sort-stylesheetsをトリガーしてください。
ブラウザコンソールでリロード理由を確認してください。一般的な原因:テーマ変更(例:フロントエンドと管理テーマ間の切り替え)、CSS/JS集約状態の変更、セッション権限ハッシュの変更。これらは一貫性を確保するための期待される動作です。
一部のリンクはdrupalSettings.refreshless.prefetchExcludePathsまたはdata-turbo-prefetch="false"属性によりプリフェッチから除外されている場合があります。リンクのパスが除外リストにあるか確認してください。
refreshless_transitionsサブモジュールが有効になっていることを確認してください。トランジションオーバーレイはCSS opacityトランジションに依存しています - opacityプロパティを削除しないでください。html要素にdata-refreshless-page-transition-state属性が設定されているか確認してください。
Security Notes 5
- RefreshLessはページ状態Cookieに保存されたテーマトークンを通じてDrupalのCSRF保護を維持します。
- ページ状態Cookieはセキュリティ強化のためにデフォルトでsecureとsameSite:strict属性を使用します。
- セッション権限ハッシュの変更は完全なページリロードをトリガーし、ユーザーが常に現在の権限に適したコンテンツを見ることを保証します。
- デバッグログモジュール(refreshless_debug)は機密データを公開しないように明示的に設計されており、本番環境でも安全に使用できます。
- すべてのRefreshLessリクエストには、サーバーサイドのリクエスト識別とセキュリティポリシーに使用できる識別ヘッダー(x-refreshless-turbo)が含まれています。