navigation-timing icon indicating copy to clipboard operation
navigation-timing copied to clipboard

How should prefetch be exposed?

Open jeremyroman opened this issue 4 years ago • 7 comments

We're working on navigational prefetch and think it would be useful for developers to, at a minimum, be able to tell whether the page was prefetched (so they can look at their analytics through this lens).

It seemed to me that the navigation timing API (and friends) might provide a natural place for this to be exposed, assuming we can do so in a way that suitably private, since it feels like information about navigation load performance much like the rest of PerformanceNavigationTiming.

A few sketches of what this could look like:

Boolean describing the navigation itself

performance.getEntriesByType('navigation')[0].prefetched;

partial interface PerformanceNavigationTiming {
    readonly attribute boolean prefetched;
};

Interface attached to the navigation

performance.getEntriesByType('navigation')[0].prefetchInfo?.prefetchUsed;

partial interface PerformanceNavigationTiming {
    readonly attribute PerformancePrefetchInfo? prefetchInfo;
};

interface PerformancePrefetchInfo {
    readonly attribute boolean prefetchUsed;
    readonly attribute DOMHighResTimeStamp duration;
    // other members describing the prefetch and possibly why it was not used
};

Separate event describing the prefetch, possibly with its (negative) start time adjusted to preserve privacy (at least if cross-origin). Implies including all the redirect, transfer size, TLS negotiation, etc timing info. ordinarily available for other resources.

performance.getEntriesByType('navigationprefetch')[0]?.prefetchUsed;

interface PerformanceNavigationPrefetchTiming : PerformanceResourceTiming {
    readonly attribute boolean prefetchUsed;
    // other members etc
};

We should of course consider whether information must be censored/omitted in some/all cases to avoid cross-site tracking vectors, but I actually suspect this is not a major issue since a site can always associate a prefetch with the associated navigation (e.g., by embedding a unique identifier in the response).

@npm1 @horo-t @buettner

jeremyroman avatar Oct 26 '21 20:10 jeremyroman

The first option seems fine to me. What's the navigationStart when prefetch is used?

npm1 avatar Oct 29 '21 16:10 npm1

What's the navigationStart when prefetch is used?

It's still after the user clicks the link (or otherwise starts a navigation), in my view.

jeremyroman avatar Feb 03 '22 04:02 jeremyroman

I want to +1 to what Dan said in the WebPerfWG that resource timing seems to be a more appropriate place for this.

I assume we can't use existing timing attributes to implicitly expose whether a page is fetched? If not, then I wonder if another option could be to introduce a new timing attribute to do expose that implicitly?

sefeng211 avatar Feb 03 '22 18:02 sefeng211

I assume we can't use existing timing attributes to implicitly expose whether a page is fetched? If not, then I wonder if another option could be to introduce a new timing attribute to do expose that implicitly?

I think it's possible. For sake of argument...

  • Set NavigationType to prefetch
  • Rest of variables are no different from cache or SW fetch case

Looking from the outside, a successful (adopted) prefetch looks the same to having a resource in memory / disk cache.

igrigorik avatar Feb 04 '22 22:02 igrigorik

Yoav and I will review the previous discussion and will present options in a future WebPerf WG call to move this forward.

nicjansma avatar Apr 07 '22 13:04 nicjansma

So it seems like we have multiple options here:

  • Recognize that any resource can be prefetched, and hence add a "prefetch" indicator on PerformanceResourceTiming, as @danshappir and @sefeng211 suggested.
  • Add a "prefetch" indicator on PerformanceNavigationTiming, either as a stand alone boolean, or as part of the NavigationType enum
    • The latter would would mean that a prefetched navigation can't be any of the other types. We'd need to define e.g. what happens when a prefetched navigation is reloaded, etc.

I tend to agree that an indicator on the ResourceTiming entry (which NavigationTiming will inherit) may be a better fit. This seems related to https://github.com/w3c/resource-timing/issues/303 as well as directly exposing if a resource was fetched from the cache (compared to today's jumping through hoops with transferSize that is required to get that info).

/cc @noamr

yoavweiss avatar Apr 25 '22 14:04 yoavweiss

Discussed on Apr 28 WebPerf WG call: https://w3c.github.io/web-performance/meetings/2022/2022-04-28/index.html

Summary:

  • It seems fine to expose prefetch and Critical-CH signals orthogonally.

nicjansma avatar May 11 '22 14:05 nicjansma