daisuzz.log

Safariの「戻る」「進む」操作を行ってページを復元したときにJavaScriptを実行させる方法

Safariでブラウザの「戻る」「進む」ボタンを押したときの挙動でハマったところがあったので備忘録としてまとめます。

bfcacheとは

SafariやFirafoxでは「進む」「戻る」操作を行うと、bfcache(back forward cache)という仕組みでページを復元します。

bfcacheは、JavaScriptなど動的なスクリプトの実行結果の状態や、画像,動画などのリソースをブラウザ上にキャッシュとして保存することで、スクリプトを再実行したり、リソースを取得するためにリクエストを再送することをせずにページを復元することができます。 bfcacheについてはWebKitのブログを読んでください。WebKit Page Cache I – The Basics | WebKit

Chromeではデフォルトでは有効になっていませんが、オプトインの機能として提供されています。 (Chromeでもin developmentステータスとして提供されています。Back-forward cache - Chrome Platform Status)

デメリット

bfcacheでページを復元した場合、復元時にJavaScriptが実行されないことで期待した画面が出力されないことがあります。

例えば、入力項目によってボタンのenable/disableを判定するような処理がある場合、適切にコードを書いていないと、bfcacheによってページが復元されたときにJavaScriptが実行されないことで、ボタンがdisableで表示され続けて押下できなくなるなどの問題が起こりえます。

対策

こうした問題を防ぐためには、ブラウザの「進む」「戻る」操作を検知する必要があります。 ブラウザの「進む」「戻る」操作を検知するためには、pageshowイベントを捕捉し、さらにevent.persistedの値を利用します。 event.persistedPageTransitionEventオブジェクトのプロパティで、ページをキャッシュから復元した場合場合true、それ以外はfalseを返します。 以下のように書くことで、bfcacheによってページが復元された場合でも任意の処理を実行させることができます。

window.addEventListener("pageshow", (event) => {
  if (event.persisted) {
    // 任意の処理
  }
})

参考

WebKit Page Cache I – The Basics | WebKit

Back-forward cache - Chrome Platform Status)

Window: pageshow イベント - Web API | MDN

PageTransitionEvent - Web API | MDN