Fast History Navigation

Fast History Navigation

[49] Webブラウザーは、ハイパーリンクをたどって次のページに進んだ時、 元のページの Document オブジェクトレンダリングに必要な情報をセッション履歴エントリー内に保存しておき、 次の「戻る」操作でそれを再利用することができます。これによって履歴操作による再レンダリングがかなり高速化できます。

[50] 履歴操作による再利用を見越したデータの保存を bfcache といいます。 Webブラウザーbfcache を実装する義務はありませんが、 多くのブラウザーが実装しています。 HTML Standardbfcache を適用できる条件を規定しています。 (適用義務はなく、 メモリー利用量等を勘案していつでもキャッシュを廃棄できます。)

[51] bfcache による再利用を考慮したページの表示開始や表示終了で発火されるイベントとして、 pageshowpagehide があります。

仕様書

セッション履歴エントリーにおける文書

[21] 利用者エージェントは、現在エントリー以外のセッション履歴エントリー文書スクリプトから参照されていないものについて、 文書を捨てることにしても構いません。 >>20

[23] 利用者エージェントがいつキャッシュを保持し続けるべきか、 いつ捨てるべきかは HTML Standard としては規定していません >>20

[25] 利用者エージェントは、利用者体験と利用可能なメモリー等の資源の制約のバランスを考慮して保持するかどうかを決められます。
[60] HTTPキャッシュに対する指示である Cache-Control: ヘッダーの指示を bfcache に適用する義務はありません。

[22] 捨てられた場合、利用者またはスクリプトにより再度そのページに遷移した時は、 新たにそのページを読み込む (エントリー更新navigate を実行する) ことになります >>20

[24] 捨てたかどうかによってセッション履歴に関する処理に影響があってはなりません。 文書が捨てられていて新たに読み込み直した場合は、同じ文書を共有していた他のセッション履歴エントリー文書も同じ新しい文書としなければなりません >>20

[28] しかしながら、捨てて再 navigate して同じ状態が復元される保証はありません。 (むしろ一般には異なる状態になります。) ネットワークが切断されて接続できなくなれば、 以前は通常の文書だったものがネットワークエラーの表示に変わったりします。

[40] 安全メソッドでは無いなら、自動的に再 fetch するのは好ましくありませんから、 エラー文書がかわりに表示されるべきと思われます。利用者が明示的に再読込したら、 再度 fetch するべきです。

[61]navigate におけるキャッシュ指令の挙動

イベント

[35] pagehide は、文書のunload時に発火されることがあります。

[33] 文書page showing フラグは、 pageshowpagehide の整合性を保つためのフラグです >>32文書作成時の初期値はです >>32。両イベントの発火により値が変化します (履歴の探索文書のunloadstops parsing 参照)。

PageTransitionEvent インターフェイス

[42] PageTransitionEvent インターフェイス >>41 は、 pageshow/pagehide イベントと共に用いられます。 文書環境ワーカー環境晒されています >>41

[44] PageTransitionEvent インターフェイスは、 他の Event インターフェイス同様のコンストラクターを持ちます >>41。 初期化のための辞書は PageTransitionEventInit です >>41

[43] PageTransitionEvent インターフェイスは、 Event インターフェイス継承しています >>41PageTransitionEventInit 辞書は、 EventInit 辞書継承しています >>41

PageTransitionEvent インターフェイス persisted 属性

[45] PageTransitionEvent インターフェイスおよび PageTransitionEventInit 辞書は、boolean 型の読み取り専用IDL属性 persistedを持ちます >>41。 初期値はです >>41

[34] 文書は、 salvageable かどうかの状態を持ちます >>32。 これが persisted 属性の値として使われます。

[37] salvageable の初期値はです >>32

[36] 次の操作を行うと、 salvageableとなります。

[46] document.open では、 salvageableになったあと、 再びとなることがあります。

[38] 利用者エージェントは適宜未参照の文書を捨てられますから (>>21)、 persistedであっても、後から bfcache で再表示される保証はありません。

関連

[52] pageshow/pagehide と前後して、 Page Visibility も変化します。

歴史

bfcache (Firefox)

[1] Using Firefox 1.5 caching - MDC ( 版) https://developer.mozilla.org/ja/Using_Firefox_1.5_caching

Fast history navigation (Opera)

[2] JavaScript and History Navigation - Opera Knowledge Base ( 版) http://www.opera.com/support/kb/view/827/

Starting in Opera 9.0 Technical Preview 2, Opera attempts to detect pages that rely on this behavior, and will not use fast history navigation on those pages. This means that the page, and any scripts it contains, will be loaded from cache, and processed again when the page is loaded using the back or forward navigation. This is known as "compatible history navigation".

[5] いつ互換モードになるのかの条件は >>2 に明記されていませんが、 onloadonunload が関わっているようです。

[3] 利用者JavaScript履歴ナビゲーション・モードを指定するには、 opera.setOverrideHistoryNavigationMode 特性を使います。 値は automaticfastcompatible です。 >>2

[4] 著者スクリプト履歴ナビゲーション・モードを明示的に指定するには、 history.navigationMode 特性を使います。 値は automaticfastcompatible です。 >>2

[6] なんか、 onunload を設定しても onload が呼ばれないという情報がありました。どういうときに自動判定で互換モードになるのでしょうかね?

Page cache (WebKit)

標準化

[7] (X)HTML5 Tracking ( 版) http://html5.org/tools/web-apps-tracker?from=4230&to=4231

[8] Bug 7896 – Specify pageshow and pagehide events ( 版) http://www.w3.org/Bugs/Public/show_bug.cgi?id=7896

[9] Changeset 47824 – WebKit ( 版) http://trac.webkit.org/changeset/47824

[10] IRC logs: freenode / #whatwg / 20100113 ( 版) http://krijnhoetmer.nl/irc-logs/whatwg/20100113#l-474

[55] [giow] (2) Make pageshow/pagehide use PageTransitionEvent, to match r… (Hixie著, ) https://github.com/whatwg/html/commit/9d17f6130b0dbcd46be35d952604ae7267b653e6

[13] [whatwg] pagehide vs pagevis ( ( 版)) http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-August/040657.html

[14] Web Applications 1.0 r8160 Provide hook for pagevis. Correctly return false for event.persisted in pagehide. Define one of the variables in an algorithm. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8159&to=8160

[15] 274784 – (blazinglyfastback) Make back and forward blazingly fast and side-effect free ( ( 版)) https://bugzilla.mozilla.org/show_bug.cgi?id=blazinglyfastback

[16] IRC logs: freenode / #whatwg / 20131214 ( ( 版)) http://krijnhoetmer.nl/irc-logs/whatwg/20131214

[19] Chrome で高速にページを読み込む新しい技術のご紹介 - Google Developer Japan Blog ( 版) http://googledevjp.blogspot.jp/2015/04/chrome.html

Chrome 42 では、このコンパイル済みコードのローカルコピーを保持する拡張技術を採用することで、ユーザーがそのページに戻ってきたときにパースをダウンロードしてコンパイルする手順をすべて省略できるようになります。これによってすべてのページでコンパイル時間の 40% を削減し、モバイル端末において貴重なバッテリーの消費量を減らすことができます。

[26] Surfin’ Safari - Blog Archive » WebKit Page Cache II – The unload Event ( 版) http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/

[27] Web Applications 1.0 r8160 Provide hook for pagevis. Correctly return false for event.persisted in pagehide. Define one of the variables in an algorithm. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8159&to=8160

[47] JavaScript - ブラウザバック時にリロードさせる - Qiita ( 版) http://qiita.com/nabettu/items/48f066155f49629be83e

window.onpageshow = function(evt) {

if (evt.persisted) {

location.reload();

[48] 戻るナビゲーションのキャッシュ (Windows) ( 版) https://msdn.microsoft.com/library/dn265017(v=vs.85).aspx

キャッシュされるためには、Web ページが次の条件を満たしていることが必要です。

  • HTTP: プロトコルを使って表示される (HTTPS ページは、セキュリティ上の理由からキャッシュされません)。
  • ページで beforeunload イベント ハンドラーが定義されていない。
  • load イベントと pageshow イベントがすべて完了している。
  • ページに次のいずれも含まれない。
    • indexedDB トランザクションが保留されている。
    • Web ソケット接続が開かれているか、アクティブである。
    • Web ワーカーが動作中である。
    • Microsoft ActiveX コントロール。
  • F12 開発者ツールのウィンドウが開いていない。

[53] Issue 511340 - chromium - Investigate faster back/forward page navigation - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=511340

[54] Editorial: define Event attribute defaults through IDL · whatwg/html@0be0229 ( 版) https://github.com/whatwg/html/commit/0be02299f128cbb7c65a7ce259fdd838fd44a4b5

[56] PopStateEvent/HashChangeEvent/PageTransitionEvent are Window-only (zcorpan著, ) https://github.com/whatwg/html/commit/dec1a5809e15d29592a66147ce2bed5018121b5f

[57] Wait for pageShow event on forward/back commands (AutomatedTester著, ) https://github.com/w3c/webdriver/commit/7c56dfc5f2fefd2af437bfd61e98f9837165704a

[58] 567365 - Cache-Control no-cache on https page disables history () https://bugzilla.mozilla.org/show_bug.cgi?id=567365

[59] Microsoft Edgeでブラウザバックをした時ラジオボタンのチェックが外れる問題 - Qiita ( ()) http://qiita.com/activefactor/items/990d5e02f2f69b90b172

[62] 112564 - Cache-Control: no-cache should not affect back/forward buttons () https://bugzilla.mozilla.org/show_bug.cgi?id=112564

[63] Remove more types from document.createEvent() (ayg著, ) https://github.com/whatwg/dom/commit/5a532da58455e55b1e611161b72224d083fee7d4

[64] 22291 - Investigate benefits of a bfcache - chromium - Monorail () https://bugs.chromium.org/p/chromium/issues/detail?id=22291

[65] 2879 - Implement fast back - chromium - Monorail () https://bugs.chromium.org/p/chromium/issues/detail?id=2879

[66] 511340 - Investigate faster back/forward page navigation - chromium - Monorail () https://bugs.chromium.org/p/chromium/issues/detail?id=511340

[67] Google AdSense を埋め込むときに使われる GPThttps://securepubads.g.doubleclick.net/gpt/pubads_impl_191.jshttps://securepubads.g.doubleclick.net/gpt/pubads_impl_rendering_191.js を読み込むのですが、 このスクリプト内で unloadbeforeunloadイベントリスナーが登録されています。 (パフォーマンス計測用?) そのため bfcache が無効化されてしまうようです。

[68] Back-forward cache: web-exposed behaviour - Google ドキュメント, https://docs.google.com/document/d/1JtDCN9A_1UBlDuwkjn1HWxdhQ1H2un9K4kyPLgBqJUc/edit#heading=h.58d6ijfz2say

[70] GitHub - rakina/bfcache-explainer, https://github.com/rakina/bfcache-explainer

[69] Back-forward cache on Android - Chrome Platform Status, https://chromestatus.com/feature/5815270035685376

[71] バック/フォワードキャッシュ, , https://web.dev/bfcache/

[72] BFCache Chrome devtools () https://groups.google.com/a/chromium.org/g/bfcache-dev/c/HkgtcRIdjso?pli=1

[73] >>72 BrowsingInstanceNotSwapped

[74] HTTPS pages with Cache-control: no-store and Back/Forward Cache - Chrome Platform Status, https://chromestatus.com/feature/6705326844805120

[75] AndroidChrome で謎に BrowsingInstanceNotSwapped のために bfcache が効かなかったのですが、 chrome://flags/#back-forward-cache を有効にするとこのエラーは出なくなって普通に bfcache が使われるようになりました。

令和3年の Chrome 96 から段階的にデフォルト有効化されてるとのことですが、 未だに完全には有効化されていないのか、 端末によっては設定の更新が行き渡っていないのか事情はよくわかりませんが、 まだ無効のままの端末もあるということみたいです。

そして Chrome の DevTools もこのフラグが無効なときはその旨を表示してくれるのですが、 挙動が謎で、 navigation の種類?によってその旨のエラーを出したり、かわりに BrowsingInstanceNotSwapped を出したりするみたいです。

[76] まったく同じ端末で同じページを表示して、 iOSSafari では bfcache が効かないのに Chrome では効くことがあります。 どちらも同じ WebKit のはずなのに、このあたりはブラウザー独自の部分が影響しているみたいです。

[77] Chrome のドキュメントのどれかに、 AndroidWebView は複雑になるから bfcache に対応する予定はないと書いてありました。 埋め込みブラウザーではなく Chrome を使わないと利用者の体験が悪くなるケースがあるということ。

[78] Facebookiframeunload 使ってるせいで bfcache が効かないんだが、、、糞が

[79] iPhoneSafaribfcache (Page Cache) は適用条件が厳しい(?)らしく、 FirefoxChrome なら効くときでも Safari だと効かないことがかなりあるみたいです。 メモリー利用量なのか何なのかいまいちその条件はよくわからないのですが、 特定サイトのほとんど同じ構成のページでも情報量が多い所では効かなくて少ない所では効いたり、かと思ったら履歴移動中にさっきまで効いてたページが効かなくなってかわりにずっと効いていなかったページが効くようになったり、 とページ自体の構造と関係ない動的な何かで判断が変わってくるっぽくて。

[80] よく作り込まれてるであろう Google検索なんかでも効かないんすよね。