Coder Social home page Coder Social logo

bfcache-not-restored-reason's People

Contributors

paulirish avatar rubberyuzu avatar tunetheweb avatar yoavweiss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bfcache-not-restored-reason's Issues

Make reasons = null for cross-origin iframes?

https://github.com/rubberyuzu/bfcache-not-retored-reason/blob/main/NotRestoredReason.md#example-2-cross-origin-iframes confused me a bit because I saw blocked = true, but reasons = []. I then realized it was because you are hiding sensitive information about cross-origin iframes. But maybe this would be more obvious if reasons was null instead of the empty array? Or maybe that would be annoying for web developers to deal with. I am not sure, but I think it's worth considering.

API detection

How can a page tell that the API exists in the browser but that the current page was not eligible for BFCache?

E.g.

  1. go to a page that will not be cached
  2. click on a link
  3. go back
  4. 4 duplicate the tab

performance.getEntriesByType('navigation')[0].type will be "back_forward"

performance.getEntriesByType('navigation')[0].notRestoredReasons will be undefined.

It's impossible to tell if the API is not implemented or it's missing because BFCache is impossible for a duplicated tab.

Perhaps the field should always be present but null when BFCache was impossible. We need to be careful about "not possible for that page at that time" vs "impossible for that navigation".

Consider allowing subframes to opt in to revealing full details

From the origin trial, we know that a hard problem is that a.com is debugging BFCache in the wild and all they know is that a subframe from b.com is blocking. They cannot tell why because cross-origin reasons are not visible. b.com also cannot do anything useful to debug this in the wild because subframes do not get access to the NRR-API (it's impossible for us to identify which subframe in the reloaded page corresponds to a subframe in the original page).

One soluion to this would be to allow the b.com subframe to opt in to making its reasons visible to its parent. If there's an unbroken chain of opt-ins from the a.com frame to the b.com frame then we reveal the blocking reasons.

There's a question about how much of the tree structure we should reveal. It's probably best to keep it hidden as it may contain sensitive IDs in urls etc. Revealing that would make it harder to safely use this opt-in. If a main frame and 3rd party really want to cooperate to debug a particularly mysterious case, they could use messages and history.pushState to capture more detailed tree information.

Cross-origin iframe name.

When reviewing the intent one thing brought my attention and that is a possibility of exposing cross-origin's frame name. It's not immediately clear whether it is an original name attribute from the frame, or the value is the actual frame's name which could be changed by an application. I guess that it's meant to be just iframe.getAttribute('name') which is fine. But just in case I wanted to point it out as a possible cross-origin leak (if for example the name was taken as iframe.contentWindow.name).

notRestoredReasons not updated when page enters bfcache

As discussed here: #2 (comment)

Consider this scenario:

  • navigate to https://web.dev
  • then www.example.com (which puts www.example.com into the bfcache)
  • then hit back to return to https://web.dev. Go make a cup of tea and wait for a bit.
  • Navigate forwards to https://www.example.com and you get a notRestoredReason of "timeout". So far so good.
  • Now navigate to another site (e.g. developer.chrome.com). I would expect that to put www.example.com into the bfcache, but when I go back I still have a notRestoredReason of "timeout".
  • However it WAS put into bfcache, it's just the notRestoredReasons was not updated because of that.

Apparently this is expected:

This is an expected behavior. NotRestoredReasons are only built when unloading a document - e.g. only for non-bfcache history navigation. (spec) So if the next navigation is restored from bfcache, NotRestoredReasons are never updated, and the reasons are supposed to stay.

We have a wpt for this too.
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/external/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js

But this seems really confusing to me. We have a page that was restored from the bfcache but also a reason why it could not be put in the bfcache.

Shouldn't the notRestoredReasons be zero-ed out when a page is put into the bfcache?

Avoiding browser specific reasons

I think it would be best if we could specify all the potential bfcache blocking reasons, even if some browsers don't use all those reasons.

This would avoid a situation where, e.g., in Chrome BroadcastChannel is "x-broadcast channels", and in Safari it is `"x-BroadcastChannel". This would be frustrating for developers.

I think the way to do this would be to just have a very large list in the specification, which any browser could add to. But no browser should ship a new reason without first sending a specification pull request.

This would force the list of reasons to go through a small amount of discussion and consideration, like we do for all specifications. Which I think would be good. E.g. maybe we don't want to expose BackForwardCacheDisabledByCommandLine and BackForwardCacheDisabledByLowMemory separately, and instead we just want BackForwardCacheDisabled.

One key ingredient here might be a generic reason like "other" or "unknown" which browsers can use for cases that they think are not common enough to be worth giving specific information on.

Consider dropping non-blocking frames

Currently NRR API reports all the same-origin frames including the non-blocking ones.
This means developers have to iterate through all of them to find the blocking one.

We can consider reporting only the blocking subtrees, dropping all the non-blocking frames.

One thing we need to think about is what we do with cross-origin subframes - they never report reasons no matter if they are blocking or not. With this dropping approach, maybe it makes sense to drop all the cross-origin frames, but that could lead to confusion.

@fergald

consider dropping some fields for cross-origin subframes

When a subframe is cross-origin, we should not provide reasons, or URL. It is a bit confusing to see blocked:true and no reasons. Also a url of "" is a little odd.

We don't give an explicit signal that information was hidden (url=="" implies it). Maybe we should have a crossOrigin field or maybe we should use null for these when the subframe is cross-origin. That's an explicit signal that you can't see them vs they are empty. However that does make it a bit more likely that uncareful devs will cause exceptions.

Consider providing source location of reason in the API

Currently, according to the approved API spec (1), the API provides a string that explains the reason that prevented the document from bfcache. It should also provide the JavaScript source location of a reason to help developers further understand why the page was not served from bfcache.

Potential information to expose as a source location is: url, function name, line number, and column number. The source location itself should be optional because some reasons do not involve source location (e.g. network related reasons such as kHTTPStatusNotOK).

Questions that I can come up with are:

  1. Whether the field for a function name should be optional or not. A line number, column number, and url should never be null as long as there's a source location, but there can be no function name provided when the reason is used in an anonymous function. Should it be an empty string or null?
  2. Whether it should provide a file name (foo.js) or an url (https://a.com/foo.js). Since there can be multiple files that have the same name, I think it is okay to provide a url while it can be pretty long.

(1): https://github.com/whatwg/html/pull/9360/files#diff-41cf6794ba4200b839c53531555f0f3998df4cbb01a4d5cb0b94e3ca5e23947dR94947

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.