1. 序論
~browser実装は、 `back/forward cache^en — 略して “`~BF~cache@~HTMLnav#_bf-cache$( `BFCache^en )” — 【(履歴を)後方/前方へ辿るとき利用される~cache】 を備える。 利用者が,ある文書から他所へ~navigateした後でも、[ 当の文書は、 `全部的に作動中$でない状態として~cacheされる ]こともあり,[ 利用者が~navigateして戻ってきたとき ]に再利用されるかもしれない。 ~~過去においては、[ 多くの~APIは、 `全部的に作動中$でない文書~用の~supportを指定していなかった ]ため,[ ~pageを~BF~cache内に~cacheする様々な~UA ]による~supportを難しくしていた — その結果、 実質的に[ 前後へ行き来するよう~navigateするときの利用者~体験 ]は最適ではなかった,あるいは[ 様々な異なる~BF~cacheの実装における挙動において,非互換化や相違点 ]さえ導入していた。 ◎ Browser implementations may have a back/forward cache, or "BFCache" for short. After a user navigates away from a document, the document might be cached in a non-fully active state, and might be reused when the user navigates back. In the past, many APIs have missed specifying support for non-fully active documents, making them hard to support in various user agents that cache pages in the BFCache, effectively making the user experience of navigating back and forth less optimal, or even introducing breakages or differences in behavior in various different implementations of BFCache.
新たな~API用に~BF~cacheの~supportを指定することにより、 ~web開発者は,[ 当の~APIを利用する ]か[ 瞬時な履歴~naviを通して,より高処理能な閲覧~体験を与える ]かを選ぶ必要はなくなる。 今後, `すべての特能は、~BF~cacheの~supportを既定で備える^strongべきである — 文書は、 各~navi回におけるかなりの割合で — 破壊される代わりに — 実際に~BF~cacheされるので。 ◎ By specifying BFCache support for new APIs, web developers do not need to choose between using the API and giving a more performant browsing experience through instant history navigations. Going forward, all features should have BFCache support by default, as documents are actually BFCached on navigation instead of getting destroyed for a sizable chunk of navigations.
注記: 文書は、 ~BF~cache法に関係しない他の理由で`全部的に作動中$でなくなることもアル — 当の文書を保持している `iframe$e が切離されたときなど。 以下に与える助言には、 そのような事例には関連しないものもある — そのような文書は、 `全部的に作動中$に戻ることは決してないので。 ◎ Note: It is possible for a document to become non-fully active for other reasons not related to BFcaching, such as when the iframe holding the document gets detached. Some advice below might not be relevant for those cases, since the document will never return to fully active again.
2. 当の特能は、いつ~BF~cacheについて~careするべきか?
当の~APIが,次に挙げるいずれかの分類に該当する`何か^strongを行う場合: ◎ If your API does things that fall into any of the below categories:
- “外側” から文書とヤリトリする (例:ある文書へ情報を送信する) ◎ Interacts with a document from the "outside" (e.g. sends information to a document)
- 文書~間での[ ヤリトリ/資源の共有 ]をアリにする (例:~lockを保持する) ◎ Makes cross-document interaction/resource sharing possible (e.g. holding locks)
- 文書が[ 利用者により他所へ~navigateされた/ 【利用者が履歴を辿った結果】復旧された ]後に[ `全部的に作動中$でない(~BF~cacheされた)状態 ]に保たれたとき, 当の文書は(破壊される代わりに)~~不正に機能し得る (例:当の文書~内に保存された状態は、 複数回の~naviにわたらないものと期待されている) ◎ May malfunction when a document is kept in a non-fully active (BFCached) state (instead of getting destroyed) after the user navigates away from it or gets restored (e.g. expects that a state saved in the document won’t span multiple navigations)
…場合、 以下の指針に従って,[ それが(~BF~cacheされた)`全部的に作動中$でない文書でどう働くか ]を指定するべきである。 共通的な~antipatternを避けるためには、 `§ ~antipattern@#antipatterns$も見よ。 ◎ You should specify how it works with non-fully active (BFCached) documents, following the guidelines below. See also the § 2.2 Antipatterns section to avoid common antipatterns.
2.1. ~API設計~指導
2.1.1. 動作は、全部的に作動中か検査することで通過制御すること
文書の状態を更新し得る動作を遂行するときは、 当の文書は,[ `全部的に作動中$でないかもしれず、 利用者の視点からは “存在しないもの” と見なされる ]ことを自覚すること。 このことは、 そのような文書は,[ 更新を受信する/動作を遂行する ]べきでないことを意味する。 ◎ When performing actions that might update the state of a document, be aware that the document might not be fully active and is considered as "non-existent" from the user’s perspective. This means they should not receive updates or perform actions.
注記: 文書が`全部的に作動中$であっても, 利用者にとっては “存在しないもの” として知覚されることはアル — 当の文書が,`予め具現化された内容を表示している@https://wicg.github.io/nav-speculation/prerendering.html$ときなど。 そのような文書の挙動は、 `全部的に作動中$でない文書とは異なり得る — ここに与える指針は、[ `全部的に作動中$でない(~BF~cacheされた)文書を取扱うために限り書された ]ものなので,適用-可能でないであろう。 ◎ Note: It is possible for a fully active document to be perceived as "non-existent" by users, such as when the document is displaying prerendered content. These documents might behave differently than non-fully active documents, and the guidelines here might not be applicable to them, as it is written only for handling non-fully active (BFCached) documents.
文書が`全部的に作動中$でない間に起こるものは、 多くの事例では,決して起こらなかったかのように扱われるべきである。 文書が[ 再び`全部的に作動中$になった後には、 非新鮮な情報を保持しない ]ことを確保するために,文書を “更新する” 方がイミを成す場合、[ `§ 全部的に作動中かどうかの変化を~listenすること@#listen-fully-active$による~pattern ]を考慮すること。 ◎ In many cases, anything that happens while the document is not fully active should be treated as if it never happened. If it makes more sense to "update" a document to ensure it does not hold stale information after it becomes fully active again, consider the § 2.1.2 Listen for changes to fully active status pattern below.
~APIのうち,情報~更新を周期的に送信するもの — `Geolocation API^cite の `watchPosition()@~GEOLOCATION#dom-geolocation-watchposition$c など — は、 文書は もはや全部的に作動中でなくなった場合には,そのような更新を[ 送信する/後で到着するよう~queueする ]べきでない。 代わりに、[ 当の文書が再び作動中になったときに限り,更新の送信を再開する ]か,場合によっては[ そのときからの最新な情報を伴う 1 個の更新を送信する ]べきである。 ◎ APIs that periodically send information updates, such as Geolocation API’s watchPosition() should not send updates if the document is no longer fully active. They also should not queue those updates to arrive later. Instead, they should only resume sending updates when the document becomes active again, possibly sending one update with the latest information then.
注記: 当の動作が[ 当の文書が`全部的に作動中$である場合に限り満たされ得る,ある種の検査 ] — 当の~top-level閲覧~文脈は`~system~focus$を有しているか否か検査するなど — によりすでに保護されている場合、 全部的に作動中かどうかの検査は必要ないかもしれない。 しかしながら、 ある種の検査 — 例:`一過な作動化を有して$いるか否か — は,[ 文書が全部的に作動中でない場合でも満たされ得る ]ことに気を付けること。 次も見よ ⇒ `§ 文書ごとの状態や~dataは~naviの後も持続し得ることを自覚すること@#per-document-state$ ◎ Note: If the actions are already protected by certain checks that can only be satisfied if the document is fully active, such as checking if the top-level browsing context has system focus, fully active checks might not be needed. However, be careful of certain checks like transient user activation, which can be true even if a document is not fully active. See also the § 2.1.5 Be aware that per-document state/data might persist after navigation section.
2.1.2. 全部的に作動中かどうかの変化を~listenすること
`全部的に作動中$であった文書が そうでなくなったときは、 破棄された文書と類似な仕方で扱われるべきである。 文書は、 共用~資源への排他的な~accessを維持してはナラナイ — [ 新たに発行される要請はないこと, 新たに入って来る要請を許容する接続は終了されること ]を確保しなければナラナイ。 `全部的に作動中$でなかった文書が,再びそうなったときは、 適切な場合には,接続を復旧できる。 ◎ When a document goes from fully active to non-fully active, it should be treated similarly to the way discarded documents are treated. The document must not retain exclusive access to shared resources and must ensure that no new requests are issued and that connections that allow for new incoming requests are terminated. When a document goes from non-fully active to fully active again, it can restore connections if appropriate.
`全部的に作動中$であった文書が そうでなくなる変化を~listenするためには、 `文書~unload時の片付け手続き$内に段を追加すること。 `全部的に作動中$でなかった文書が そうなる変化を~listenするためには、 `文書を作動化し直す$手続き内に段を追加すること。 ◎ To listen to changes from fully active to non-fully active, add a step in unloading document cleanup steps.\ Meanwhile, to listen to changes from non-fully active to fully active, add a step to reactivate a document.
~web作者は,[ `pagehide@~HTMLindex#event-pagehide$et ~eventの中から片付けを手動で行うことも (例:当の資源を解放する/接続を断つ), `pageshow@~HTMLindex#event-pageshow$et ~eventの中から,それを復旧することも ]できるが、 これを~API設計から自動的に行うようにすれば,[ 既定では、 当の文書は,~naviの後も生きたまま保たれる ]ことを許容する — その結果、 ~web~appがきちんと機能する方へ導く見込みも高まる。 ◎ While web authors can manually do cleanup (e.g. release the resources, sever connections) from within the pagehide event and restore them from the pageshow event themselves, doing this automatically from the API design allows the document to be kept alive after navigation by default, and is more likely to lead to well-functioning web applications.
~APIは,~liveな接続を作成する場合には、 当の接続を[ 静止でき,場合によっては後で再開できる/ ~closeでき,場合によっては後で~openし直せる ]。 また、 既存の進行中な要請を完了するまで,当の接続を~openしたままにして、 適切になる場合は(例:資源の読込n),[ 後で復旧されたとき,要請の結果で当の文書を更新する ]こともアリである。 ◎ APIs that create live connections can pause/close the connection and possibly resume/reopen it later. It’s also possible to let the connection stay open to complete existing ongoing requests, and later update the document with the result when it gets restored, if appropriate (e.g. resource loads).
~APIは,排他的でない資源を保持する場合には、[ `全部的に作動中$であった文書がそうでなくなったとき,当の資源を解放する/ 再び`全部的に作動中$になったとき,それを獲得し直す ]ことも可能になり得る ( `Screen Wake Lock API^cite は、 前者をすでに`行なっている@~SCREEEN-WAKELOCK#handling-document-loss-of-full-activity$)。 ◎ APIs that hold non-exclusive resources may be able to release the resource when the document becomes not fully active, and re-acquire them when it becomes fully active again (Screen Wake Lock API is already doing the first part).
注記: 資源の型によっては、 これは,適切にならないこともある — 例:排他的な~lockが保持されていた場合、[ 別の~pageが,解放された~lockを~~獲得することもある ]ので,単に[ 当の~lockを解放して,`全部的に作動中$になったとき獲得し直す ]ことはできない。 そうすることは、[ これが起きたことを当の~pageに通達する~APIがある場合は、 受容-可能になり得る ]が,[ これが~BF~cacheでしか起こらない場合、 多くの~pageは,それ用に準備されないと見込まれる ]ことに注意。 ~BF~cacheを~supportするのはアリでない場合、 下に述べる[ `§ 全部的に作動中でない文書は、~supportし得ない状況では破棄すること@#discard$ ]による~patternに従うこと。 ◎ Note: this might not be appropriate for all types of resources, e.g. if an exclusive lock is held, we cannot just release it and reacquire when fully active since another page could then take that lock. If there is an API to signal to the page that this has happened, it may be acceptable but beware that if the only time this happens is with BFCache, then it’s likely many pages are not prepared for it. If it is not possible to support BFCache, follow the § 2.1.4 Discard non-fully active documents for situations that can’t be supported pattern described below.
加えて,ある文書が再び`全部的に作動中$になったとき、 `全部的に作動中$でない間に変化したものがある場合には, 外の世界の現在の状態で更新することが有用になり得る。 しかしながら,文書が~BF~cache内にある間に生じた~eventに対しては、 ~careする必要がある。 文書が`全部的に作動中$でないとき、[ すべての~eventを落とすべき事例/ 単独の~event内に最新な状態を送達するべき事例/ 各~eventを~queueするか結合された~eventを送達するのが適切になる事例 ]いずれもある。 正しい~approachは、 事例ごとに異なり,[ ~privacy, 正しさ, 処理能, 人間工学 ]を考慮するべきである。 ◎ Additionally, when a document becomes fully active again, it can be useful to update it with the current state of the world, if anything has changed while it is in the non-fully active state. However, care needs to be taken with events that occurred while in the BFCache. When not fully active, for some cases, all events should be dropped, in some the latest state should be delivered in a single event, in others it may be appropriate to queue events or deliver a combined event. The correct approach is case by case and should consider privacy, correctness, performance and ergonomics.
注記: [ 再び`全部的に作動中$になった文書へ最新な状態が送信されるようにする ]ことは、 とりわけ,既存の~APIを補修するときに重要になる — これらの~APIの現在の利用者は、 常に最新な情報が伴われるものと期待するからである。 状態~更新を落とすと、 当の文書は非新鮮な情報を伴ったままになり得る — その結果、 既存の~siteを[ 期待されない, かつ検出するのが難しい非互換化 ]に至らせ得る。 ◎ Note: Making sure the latest state is sent to a document that becomes fully active again is especially important when retrofitting existing APIs. This is because current users of these APIs expect to always have the latest information. Dropping state updates can leave the document with stale information, which can lead to unexpected and hard-to-detect breakage of existing sites.
`gamepadconnected@~GAMEPAD#dfn-gamepadconnected$et ~eventは、 文書が`全部的に作動中$でない間に ~gamepadが接続された場合、 再び`全部的に作動中$になったとき,当の文書へ送信され得る。 当の~gamepadが何回か接続され切断された場合、 送達される~eventは,最後に接続されたときのそれに限るべきである (これは、 まだ指定されていない — `課題@https://github.com/w3c/gamepad/issues/149$を見よ。) ◎ The gamepadconnected event can be sent to a document that becomes fully active again if a gamepad is connected while the document is not fully active. If the gamepad was repeatedly connected and disconnected, only the final connected event should be delivered. (This is not specified yet, see issue)
地理所在その他の物理的な~sensor用には、 `全部的に作動中$でない間に起きたことについての情報は,送達しないべきである。 ~eventは、 単純に,文書が`全部的に作動中$になったときから再開するべきである。 しかしながら,これらの~APIは、[ 当の文書は、 当の~APIにより通常に保証されるとおり,最新な情報を有する ]ことを確保するため、 文書が再び`全部的に作動中$になったときには,[ その状態を検査して,状態s更新を送信するべきかどうか決定する (例:現在の所在は、 文書が全部的に作動中でなくなった時点の所在から遠く離れているか?) ]べきである。 ◎ For geolocation or other physical sensors, no information about what happened while not fully active should be delivered. The events should simply resume from when the document became fully active. However, these APIs should check the state when the document becomes fully active again, to determine if a status update should be sent (e.g. is the current location far away from the location when the document becomes not fully active?), to ensure the document has the latest information, as guaranteed by the API normally.
[ ~network接続や~stream ]用には、[ `全部的に作動中$でない間に受信された~data ]は,[ 文書が再び`全部的に作動中$になったときに限り,送達される ]べきである。 ~streamは、 多数の[ 少量な~dataを伴う~event ]を作成することもあり,より少数の[ より多量な~dataを伴う~event ]として送達することもできる。 ◎ For network connections or streams, the data received while not fully active should be delivered only when the document becomes fully active again, but whereas a stream might have created many events with a small amount of data each, it could be delivered as smaller number of events with more data in each.
2.1.3. 複数~文書にわたる~APIからは、全部的に作動中でない文書は省略すること
`全部的に作動中$でない文書は,観測-不能になるべきなので、 ~APIは,それらを存在しないものとして扱うべきである。 それらは、 複数~文書にわたる~API (例: `clients.matchAll()@~SW1#dom-clients-matchall$c, `window.opener@~WINDOW#dom-window-opener$c ) を通して “外側の世界” から可視になるべきでない。 ◎ Non-fully active documents should not be observable, so APIs should treat them as if they no longer exist. They should not be visible to the "outside world" through document-spanning APIs (e.g. clients.matchAll(), window.opener).
注記: 複数~文書にわたる~API自体が比較的~稀なので、 これは,稀にしかないはずである。 ◎ Note: This should be rare since cross-document-spanning APIs are themselves relatively rare.
`BroadcastChannel$I は、 その `postMessage()@~HTMLcomms#dom-broadcastchannel-postmessage$c ~methodの中で, 他の閲覧~文脈へ~messageを送信する前に`全部的に作動中$かどうか検査する。 【!#broadcasting-to-other-browsing-contexts:fully-active】 ◎ BroadcastChannel checks for fully active before sending messages to other browsing contexts.
`clients.matchAll()@~SW1#dom-clients-matchall$c は、 現時点では,~clientが`全部的に作動中$か否かを判別しないが、 正しい実装が返す~clientは,`全部的に作動中$なものに限るべきである (`課題@https://github.com/w3c/ServiceWorker/issues/1594$を見よ)。 ◎ clients.matchAll() currently does not distinguish between fully active and non-fully active clients, but correct implementations should only return fully active clients. (See issue)
2.1.4. 全部的に作動中でない文書は、~supportし得ない状況では破棄すること
`全部的に作動中$でない文書を~supportするのは, ある種の事例ではアリでない場合: ◎ If supporting non-fully active documents is not possible for certain cases,\
- 当の状況が利用者が他所へ~navigateした後に起こる場合には ⇒ `文書を破壊する$ことにより,~supportし得ないことを明示的に指定すること。 ◎ explicitly specify it by discarding the document| if the situation happens after the user navigated away,\
- 当の状況が当の文書から他所へ~navigateする前か その間に起こる場合には ⇒ ~naviの後に自動的に破棄されるよう,文書の`回復可能~状態$docを ~F に設定すること。 ◎ or setting the document’s salvageable) bit to false if the situation happens before or during the navigation away from the document, to cause it to be automatically discarded after navigation.
注記: これは,稀であり、 おそらく,旧い~APIを補修するときに限り利用されるべきである — 新たな~APIは、 常に,~BF~cacheと伴にきちんと働くよう~~努めるべきなので。 ◎ Note: this should be rare and probably should only be used when retrofitting old APIs, as new APIs should always strive to work well with BFCache.
`WebSockets@~WEBSOCKET$cite は、 `文書~unload時の片付け手続き$【!~HTMLLS#unloading-documents:concept-document-salvageable-7】の間に,`回復可能~状態$docを ~F に設定する。 ◎ WebSockets sets the salvageable bit to false during unload.
`clients.claim()@~SW1#dom-clients-claim$c が~callされたときは、 `全部的に作動中$でない~clientを待機するべきでない — 代わりに、 `全部的に作動中$でない~client文書は,破棄されるようにするべきである (これは、 現時点では指定されてない — `課題@https://github.com/w3c/ServiceWorker/issues/1594$を見よ)。 ◎ Calling clients.claim() should not wait for non-fully active clients, instead it should cause the non-fully active client documents to be discarded. (This is currently not specified, see issue)
2.1.5. 文書ごとの状態や~dataは~naviの後も持続し得ることを自覚すること
文書は,~naviの後であっても再利用され得るので、[ 文書の存続期間に何かを束ねることは、 ~naviの後にも それを再利用することを意味する ]ことを自覚すること。 これが望ましくない場合、 次を考慮すること ⇒ `全部的に作動中$かどうかの状態に対する変化を~listenして, 必要に応じて片付けを行う (`§ 全部的に作動中かどうかの変化を~listenすること@#listen-fully-active$ を見よ)。 ◎ As a document might be reused even after navigation, be aware that tying something to a document’s lifetime also means reusing it after navigations. If this is not desirable, consider listening to changes to the fully active state and doing cleanup as necessary (see the § 2.1.2 Listen for changes to fully active status pattern above).
`居残な作動化を有して$いるか否かは、 “最後の作動化~時刻印” により決定され,文書に束ねられる。 このことは、 利用者が ある文書に対し作動化を誘発して以降ずっと — 利用者が他所へ~navigateしてから再び戻ってきた後でも — 居残な作動化を有し続けることを意味する。 `これをめぐる論点@https://github.com/whatwg/html/issues/6588#issuecomment-1157244943$は,[ 他の挙動(例:~focus)と比較した結果、 それでよいと結論した ]が、 あらゆる特能~仕様は,[ このことについて考して、 当の特能にとって何が最善に働くかを裁定する ]べきである。 ◎ Sticky activation is determined by the "last activation timestamp", which is tied to a document. This means after a user triggers activation once on a document, the document will have sticky activation forever, even after the user navigated away and back to it again. The discussion around this concluded that this is OK after comparing with other behaviors (e.g. focus), but every feature specification should think about this and decide what works best for the feature.
2.2. ~antipattern
この節は、 基本的に,設計~指導にて言及したものの逆である。 仕様を書するときは、 `次を期待しないこと^strong: ◎ This is basically the reverse of what is mentioned in the design guidance. When writing specifications, do not do these:
-
[ 当の文書~内に生きたまま保たれたもの(接続, 等々) ]あるいは[ 当の文書の存続期間に束ねられたもの ]は、 ~naviにおける文書の破壊に伴って,自動的に[ 破壊される/切断される, 等々 ]ことになる。 ◎ Expect that things kept alive in the document (connections, etc) or that are otherwise tied to the document lifetime will be automatically destroyed/disconnected/etc on navigation along with document destruction.\
これは間違いである ⇒ 文書は、 ~naviの後も~BF~cache内に生きたまま保たれるかもしれず, 後で復旧され得るので。 ◎ This is wrong because documents might be kept alive in the BFCache after navigation, and can potentially get restored later.\
これを取扱う方法は、 次に挙げる手引きを見よ ⇒# `§ 動作は、全部的に作動中か検査することで通過制御すること@#gate-fully-active$/ `§ 全部的に作動中かどうかの変化を~listenすること@#listen-fully-active$ ◎ See these guides on how to handle this: • § 2.1.1 Gate actions with fully active checks • § 2.1.2 Listen for changes to fully active status
-
文書が生きたままな場合、 利用者からも生きたままとして知覚され, したがって他の文書と同様に扱える。 ◎ Expect that if a document is alive, it is also perceived as alive by the user, and thus can be treated like any other document.\
これは間違いである ⇒ ~BF~cacheされた文書は “生きたまま” であるが、 実際には,利用者の視点からは消え去っており(利用者が他所へ~navigateするに伴い)、 他の文書と同じ仕方で扱われるべきでないので。 ◎ This is wrong because documents that are BFCached are “alive”, but they’re actually gone from the perspective of the users (as they have navigated away), and thus shouldn’t be treated the same way as other documents.\
これを取扱う方法は、 次に挙げる手引きを見よ ⇒# `§ 複数~文書にわたる~APIからは、全部的に作動中でない文書は省略すること@#omit-non-fully-active$/ `§ 動作は、全部的に作動中か検査することで通過制御すること@#gate-fully-active$ ◎ See these guides on how to handle this: • § 2.1.3 Omit non-fully active documents from APIs that span multiple documents • § 2.1.1 Gate actions with fully active checks
-
文書は一度しか “示されない”/~navigateされない。 ◎ Expect that a document is only “shown”/navigated to once.\
これは間違いである ⇒ 文書は、 未来の履歴~naviに伴い復旧され得る — したがって、 利用者は同じ文書へ複数回~navigateでき,同じ文書が複数回~再利用され得るので。 ◎ This is wrong because documents can potentially get restored on future history navigations, and thus the user can navigate to and reuse the same document multiple times with multiple navigations.\
これを取扱う方法は、 次に挙げる手引きを見よ ⇒# `§ 全部的に作動中かどうかの変化を~listenすること@#listen-fully-active$/ `§ 2.1.5 文書ごとの状態や~dataは~naviの後も持続し得ることを自覚すること@#per-document-state$ ◎ See these guides on how to handle this: • § 2.1.2 Listen for changes to fully active status • § 2.1.5 Be aware that per-document state/data might persist after navigation