bfcache が無効化される原因を調べて対処できたので一部ページで発生していた問題が解決できました
unload のつける・つけないで簡単に有効と無効を切り替えられるので実際に試せるページを用意しました
https://nexpr.gitlab.io/public-pages/bfcache-test/
index.html に 「bfc on」 と 「bfc off」 のリンクがあり on だと bfcache が有効で off だと無効です
off の方は unload リスナをつけて bfcache を無効化しています
それ以外のページの内容は一緒です
最初に開く画面では input が 3 つあって 入力するとそれぞれ下に入力された値を表示します
lit-html を使って入力値を管理しています
適当に入力した状態で下にあるリンクをクリックします
特に何もない画面が表示されるので ブラウザの戻るボタンで戻ります
bfcache が有効な方では input の入力値もその下の表示も最後の状態が復元されています
それに対して無効な方では input は復元されているものの下の方の表示は復元されていません
無効だと初期状態から画面を作っているので input も下の表示も空になるはずです
しかし input はブラウザの便利機能として最後の入力状態が復元されます
そのせいで変数で持ってる内部状態と input に表示されているものが異なる状態になってしまってます
なにか入力すれば内部状態と同期されますが 画面では表示されているので ユーザーは入力されていると思ってそのまま保存するかもしれません
その場合は内部では未入力状態なので意図しないデータで保存されてしまいます
これまではブラウザの復元を無効にする手間が必要でしたが bfcache があればこの問題は発生しません
unload リスナをつけないようにしたり no-store をヘッダーにつけないようにしたりで bfcache が有効になるようにすれば解決できます
ただ 拡張機能が原因で bfcache が無効になることがあるのが厄介なんですよね
拡張機能が原因ならユーザーが原因なので無効にしてください でいいですけど自分で使っている範囲でも影響を受けることがありますし
ところで今回は lit-html を使ってますがその他ライブラリでも基本同じ結果です
ただ React では入力時に初期値(属性)も更新するので ブラウザが現在値と初期値が等しく更新されていないとみなすため復元処理が発生しません
この問題の対処としては良いのですが 入力のたびに本来変更が不要な属性まで変えて初期値を更新するのはどうかと思いますし それが問題点になって React の悪い部分として挙げられることもあるものです
bfcache が無効化される場合用の対処方法として あまり積極的には使いたくない方法です
以前 bfcache が Chrome に実装されたときにいくつかのページを試すと bfcache が使われてるページとそうでないページがあって なぜ使われたり使われなかったりするのか はっきりとした原因はわかりませんでした
その後いつのころからか devtools の Application タブに 「Back/forward cache」 という項目が増えていました
「Test back/forward cache」 というボタンがあるので確認したいページを開いて押します
ページがリロードされて bfcache が有効化どうかを表示してくれます
無効の場合は原因も教えてくれます
ときどき原因が表示されないこともありますけど
このブログだと成功になって bfcache が有効みたいですが メインの方のブログでは成功が出たかと思ったらすぐ失敗に切り替わってます
失敗になる原因のひとつは unload ハンドラが設定されてることで 結構見かけます
他にも拡張機能で JavaScript や CSS を挿入してる場合も無効になるようです
ページのカスタムや広告ブロック系の拡張機能とは相性が悪いですね
あと HTTP のレスポンスのヘッダーに 「Cache-Control: no-store」 が付いてる場合も bfcache が無効になるようです
自分で作ったページで unload などを使ってないのに bfcache が動いてなくて調べるとこれでした
Cache-Control なんてつけた覚えはなかったのですが PHP のレスポンスではデフォルトでついてるようでした
つく場所とつかない場所があって少し困りましたが session を使うと追加されるようです
戻るボタンで戻ったときでもサーバにアクセスしてログイン状態を確認したいのならいいのかもですが 戻るだけならログインチェックなどはしなくていいと思うんです
これまで見えていた画面ですし 新規に検索したり画面を移動するとそこでログインチェックが入りますし
PHP では
で自動で Cache-Control ヘッダーを出力するのを防げるようです
その後いつのころからか devtools の Application タブに 「Back/forward cache」 という項目が増えていました
「Test back/forward cache」 というボタンがあるので確認したいページを開いて押します
ページがリロードされて bfcache が有効化どうかを表示してくれます
無効の場合は原因も教えてくれます
ときどき原因が表示されないこともありますけど
このブログだと成功になって bfcache が有効みたいですが メインの方のブログでは成功が出たかと思ったらすぐ失敗に切り替わってます
失敗になる原因のひとつは unload ハンドラが設定されてることで 結構見かけます
他にも拡張機能で JavaScript や CSS を挿入してる場合も無効になるようです
ページのカスタムや広告ブロック系の拡張機能とは相性が悪いですね
あと HTTP のレスポンスのヘッダーに 「Cache-Control: no-store」 が付いてる場合も bfcache が無効になるようです
自分で作ったページで unload などを使ってないのに bfcache が動いてなくて調べるとこれでした
Cache-Control なんてつけた覚えはなかったのですが PHP のレスポンスではデフォルトでついてるようでした
つく場所とつかない場所があって少し困りましたが session を使うと追加されるようです
戻るボタンで戻ったときでもサーバにアクセスしてログイン状態を確認したいのならいいのかもですが 戻るだけならログインチェックなどはしなくていいと思うんです
これまで見えていた画面ですし 新規に検索したり画面を移動するとそこでログインチェックが入りますし
PHP では
session_cache_limiter('');
で自動で Cache-Control ヘッダーを出力するのを防げるようです