New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 788757 link

Starred by 7 users

Issue metadata

Status: Assigned
Owner:
Last visit > 30 days ago
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug



Sign in to add a comment

Preloads of non link-rel-preload requests are stalled waiting for potential AppCache

Project Member Reported by malteubl@google.com, Nov 27 2017

Issue description

It appears that requests issued via <link rel=preload> always start before other requests seen by the preload scanner even if those have higher priority. E.g. in the example below the request for the image is made before the request for the stylesheet.


Example:
http://output.jsbin.com/mefikum/quiet

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Request order</title>
  <link rel=stylesheet href=404.css>
  <link rel=preload as=image href=404.png>
</head>
<body>
Open Chrome DevTools
</body>
</html>
 

Comment 1 by y...@yoav.ws, Nov 27 2017

Cc: kouhei@chromium.org csharrison@chromium.org
Components: -Blink>Loader>Preload Blink>Loader
The cause for preloads "jumping the queue" here is that other resources are forced to wait around for AppCache to be initialized: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp?q=HTMLDocumentParser&sq=package:chromium&dr=CSs&l=347

csharrison@ and kouhei@ - any ideas on how we can get rid of that limitation? I suspect that regardless of preload, this will result in measurable real-life speed-up for critical resources. (as they are now stalled waiting for a potential AppCache, which 99% of the time is not there)

Removing the "Preload" component as this is not preload specific.

Comment 2 by y...@yoav.ws, Nov 27 2017

Summary: Preloads of non link-rel-preload requests are stalled waiting for potential AppCache (was: Requests issued via link-rel-preload start before other requests)
I spent some time trying to optimize this so that waiting for the document element to be available isn't too slow. Maybe it makes sense to just treat preloads like normal requests and wait universally? We may end up *slightly* delaying preloads by a few ms, but it'll fix the reordering issue.

It might make sense to measure this queuing time in UMA before making the decision, but I expect the delay to be quite small.

Comment 4 by malteubl@google.com, Nov 27 2017

On my MBP this typically amounts to about 2ms in queuing difference. On my Pixel 2 it is typically about 5ms.

What is the condition for queue to become unwound?
We flush the queue when the document element is available, when the first HTML element is inserted by the parser:
https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp?rcl=902e84f0e4cb6af6e8ea7de2e1862799fdc7686b&l=55


Comment 6 by y...@yoav.ws, Nov 28 2017

I wonder if we can't simply detect the presence of `manifest` in the preloadScanner, and only delay the requests if it's present. Charlie - did you already look into something like that?
Cc: michaeln@chromium.org
Yes. I'm afraid I don't understand appcache completely but my understanding is that a "manifest" tag is not necessary for the page's loading to be controlled by the appcache.

See HTMLHtmlElement::MaybeSetupApplicationCache which is called right before dispatching the queued preloads.
Status: Assigned (was: Untriaged)
Loading triage: update status.

Comment 9 by y...@yoav.ws, Jan 1 2018

OK, so I think appcache can be relevant if any of the resources were specified by a manifest in the past.

I think a reasonable first step would be to count pages with appcached resources, but without a `manifest` attribute. If usage is low, we can just ignore that case. If it's high, we can think of tracking appcached domains in persistent storage and only delay preloading for them.

Yoav pointed me to this issue as it seems relevant to some web font loading performance auditing I’d done (looking at the default wordpress.com theme).

A few webpagetest.org results:

Baseline self hosted fonts (first render 3.4s):
https://www.webpagetest.org/result/181031_ZX_5e26f8b37715e09c6afbbfe26ecae462/#run4

Addition of `preload` for all 5 web fonts, after the CSS requests (first render 3.6s):
https://www.webpagetest.org/result/181116_7D_463c90c215204f52815968f2e65deed5/#run5

Addition of `preload` at the top of the `head` for all 5 web fonts, before any CSS requests (first render 3.8s):
https://www.webpagetest.org/result/181025_8V_f17952607dd251e4b7a26b07fc13f89d/#run6

This issue seems to be making sure that preloaded resources are hitting the server ahead of potentially higher priority ones, and in doing that, stalling those higher priority resources in many server implementations (because H2 priorities are hard[1]).

I think the best way for us to remove this hurdle from our preloader code would be to create a feature policy that opts-you out of waiting for AppCache.

I'll start an issue.


[1] https://blog.cloudflare.com/http-2-prioritization-with-nginx/

 
Cc: chrisha@chromium.org
I don't have any concerns with a feature policy to turn off appcache, but there's an effort underway to add a local database mapping origin-->features used for freezing background tabs on desktop. Could we piggy back off that and track sites that have used appcache and only block for those sites?
Yoav: why not just delay link rel preloads the same as speculative preloads? I really don't think the delay is going to be very big (just a few ms at most).
csharrison@ - you probably remember better but I was under the impression that https://codereview.chromium.org/2165653004 was introduced after complaints from the wild that preloads are needlessly delayed.
While we can certainly introduce delays for preloads, it seems like it would be better to avoid the delays for everyone other than the minority of cases that actually need it.
It would be good to measure the delay. My memory is that a lot of the delay came from the byproduct that waiting for AppCache also meant waiting for extension content scripts.

However, we fixed that in [1] so the ordering went:
1. Appcache init
2. Flush out speculative preloads
3. Run extension scripts

[1]: https://codereview.chromium.org/2042413002/
Alternatively, we could kick off *all* preloads earlier if an AppCache manifest is not present, as it will just result in a performance degradation for the minority of pages which have an AppCache but don't declare a manifest. So, punishing the misbehaving few, rather than the majority.
+1, either is reasonable. My main point is that we should be avoiding complexity for AppCache rather than adding it (e.g. by speccing new FPs that might not be necessary).

Sign in to add a comment