バックフォワード キャッシュ(BFCache)は、前のページと次のページにすぐに移動できるようにブラウザを最適化する機能です。Chrome BFCache に変更を加えるため、メッセージ ポートを使用する拡張機能に影響する可能性があります。コンテンツ スクリプトと拡張機能の間でメッセージを使用して通信する Chrome 拡張機能をお持ちの場合は、以下で拡張機能のテストと適応方法をご覧ください。
拡張メッセージ ポート
拡張機能は、メッセージ パススルーを介してコンテンツ スクリプトや他の拡張機能と通信します。メッセージを送信するには、runtime.sendMessage()
と tabs.sendMessage()
を呼び出して 1 回限りのリクエストを使用するか、再利用可能なメッセージ ポートを使用します。ポートがアクティブである限り、コンテンツ スクリプトと拡張機能のバックグラウンド スクリプトの両方がポートを再利用して、相互にメッセージを送信できます。
詳細については、メッセージ パススルーをご覧ください。
バックフォワード キャッシュ
BFCache の対象となるページから別のページに移動すると、ブラウザは、そのページのすべての状態をメモリに保持しますが、完全にアクティブな状態にはしません。ユーザーがキャッシュに保存されたページに履歴ナビゲーション(「戻る」または「進む」)を実行すると、ブラウザは BFCache からページを復元しようとします。これにより、ナビゲーションが高速化され、ユーザーのブラウジング エクスペリエンスが向上します。
ページが BFCache に保存されている間は、JavaScript の実行が許可されないフリーズ状態になります。つまり、受信したメッセージを処理できません。
詳細については、バックフォワード キャッシュをご覧ください。
拡張機能メッセージ ポートが BFCache に与える影響
つまり、BFCache 内のページにメッセージを送信する拡張機能は、キャッシュの強制排除を引き起こし、パフォーマンスに影響する可能性があります。
開いている拡張機能メッセージ ポートを持つページが BFCache に保存されると、ポートは開いたままになります。ページが BFCache から復元された後も、拡張機能サービス ワーカーはメッセージ ポートの古い参照を使用して、コンテンツ スクリプトにメッセージを送信できます。
ただし、ページがまだ BFCache にある間に拡張機能がそのメッセージ ポート経由でメッセージを投稿しようとすると、メッセージは送信されますが、ハンドラがフリーズしているため完全に配信されません。メッセージのキューイングとドロップの両方に独自の問題があるため、拡張機能がこの状況を推論して対処するのは困難です。
メッセージの損失に関連する問題を回避するため、Chrome の現在の実装では、ホストページを BFCache から強制排除し、メッセージを破棄します。ユーザーがページに戻ると、ページが新しく読み込まれ、拡張機能は新しい接続を設定できるようになります。
一方、この実装では BFCache が適用されるシナリオが制限され、パフォーマンスの向上が制限されます。特に、すべての接続に定期的にメッセージを送信するブロードキャスト メカニズムやハートビート メカニズムを使用する拡張機能では、パフォーマンスの向上が制限されます。さらに、拡張機能がコンテンツ スクリプトにメッセージを送信したときに強制排除がトリガーされるため、ウェブ デベロッパーはページの強制排除を防ぐ手段がありません。
全体的なパフォーマンスを向上させるため、新しいメッセージ ポートの動作を導入する予定です。
新しい動作: ページが BFCache に保存されたときにメッセージ チャネルを閉じる
Chrome 123 以降、開いている拡張機能メッセージ ポートを持つページが BFCache に保存されると、基盤となるメッセージ チャネルがコンテンツ スクリプト側から事前に閉じられます。その結果、すべてのメッセージポートが閉じられ、拡張機能は onDisconnect
イベントを受信します。
チャンネルが閉じられているため、ページが BFCache にある間は、ページにメッセージが送信されません。そのため、ページは拡張機能によって強制排除されません。
ページが BFCache から復元された後も、閉じられたメッセージ チャンネルは再び開かれません。拡張機能の作成者は、ページのライフサイクル イベントをリッスンし、ページが BFCache から復元されたときに新しい接続をセットアップすることをおすすめします。次に例を示します。
// content script
let port;
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// The page is restored from BFCache, set up a new connection.
port = chrome.runtime.connect();
}
});
さまざまなブラウザの担当者による WECG の会話(問題 474 の下)で詳細を確認してください。
影響
この新しい動作は、Chrome 123 でフラグによって利用可能になり、コードをテストできるようになります。詳しくは、タイムラインをご覧ください。拡張機能をテストする手順は次のとおりです。これは単純なテストのみを提供するものです。拡張機能のどの機能が問題を引き起こす可能性があるかを予測するのは難しいため、この機能を有効にしてしばらく Chrome を実行することをおすすめします。
新しい動作のテスト
Chrome 123 で試験運用版を強制的に有効にするには:
次のフラグを使用して Chrome を起動します。これにより、新しい動作が強制されます。
--enable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
ページに移動し、必要に応じて拡張機能で操作して、コンテンツ スクリプトが拡張機能へのポートを開くようにします。
別のページに移動してから元のページに戻ります。これでページは復元されますが、コンテンツ スクリプトとサービス ワーカー間のメッセージ チャンネルは切断されます。
拡張機能が通常どおり動作するかどうかをテストします。動作しない場合は、前のセクションで説明したように手動で再接続する必要があります。
以前の動作を使用して簡単な問題を特定する
この変更が行われる前は、bfcache 内のページに関連付けられたポートにメッセージを送信しようとすると、Chrome に警告が表示されていました。これは、バックグラウンドからページへのメッセージに関連する問題の一部を特定する場合に役立ちます。
- Chrome のバージョンが 123 以降であることを確認します。テストを容易にするために、Chrome Canary を使用することをおすすめします。Chrome Canary には、テストを容易にするための追加の警告が表示されます。
次のフラグを指定して Chrome を起動します。これにより、古い動作が強制されます。
--disable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
拡張機能を実行せずに BFCache の対象となるページに移動します(https://example.com/ などのシンプルなサイトなど)。BFCache チュートリアルに沿って、BFCache から復元されていることを確認します。
拡張機能をインストールして有効にし、BFCache の利用資格をもう一度テストします。手動でページを離れ、拡張機能が BFCached ページにメッセージを投稿するのに十分な時間を待ってから、ページに戻ることができます。
エビクションが発生したためにページを BFCache ではなく新しく読み込む必要があり、復元を妨げている問題が「ExtensionSentMessageToCachedFrame」である場合、この変更によって拡張機能に影響が及ぶ可能性があります。
Chrome Canary 124.0.6315.0 以降では、ページに次の警告も表示されます。
ページが BFCache から復元されていない場合に表示される警告。
拡張機能が BFCache ページにメッセージを送信していることを確認したら、前のセクションの手順に沿ってテストを強制的に有効にし、ロジックが破損していないか確認します。
リリース スケジュール
新しい動作は、Chrome 123 から段階的に導入される予定です。詳細な計画は次のとおりです。
日付 | 予定されているマイルストーン |
---|---|
2 月 15 日 | Chrome 123 Canary と Dev で、新しい動作の試験運用を開始します。 |
3 月 7 日 | Chrome 123 ベータ版で新しい動作のテストを開始します。 |
3 月 18 日 | Chrome 123 Stable の 4% のユーザーに新しい動作をリリース。 |
3 月 25 日 | Chrome 123 Stable で、新しい動作を 50% のユーザーにリリースします。 |
4 月 2 日 | テストが終了し、新しい動作がデフォルトになります。 |