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

Issue 604383 link

Starred by 8 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug



Sign in to add a comment

Add support for preloading <link rel=import> resources

Project Member Reported by kinuko@chromium.org, Apr 18 2016

Issue description

Repro:

specify link rel=preload for a subresource that is to be loaded via rel=import, e.g.:

main.html
 - having "link: </foo.html>;rel=preload" in HTTP header
 - having "<link rel=import href=foo.html>" in the html header

foo.html
 - having "cache-control: max-age=0, no-cache" in HTTP header

Expected behavior:
foo.html is preloaded and preloaded resource is used

Actual behavior:
foo.html is preloaded, and then another resource request goes network (partly due to no-cache directive), so it downloads the resource twice


Possibly related to  issue 603118 , though the other one (polymer-starter-kit) doesn't seem to have preload specified.
 

Comment 1 by kinuko@chromium.org, Apr 18 2016

More detail:

From reading the spec it looks this shouldn't happen (https://w3c.github.io/preload/#h-note4):
"NOTE: For example, if a JavaScript resource is fetched via a preload link and the response contains a no-cache directive, the fetched response is retained by the user agent and is made immediately available when fetched with a matching same navigation request at a later time - e.g. via a script tag or other means. This ensures that the user agent does not incur an unnecessary revalidation, or a duplicate download, between the initial resource fetch initiated via the preload link and a later fetch requesting the same resource."

And in the source code it looks we're trying not to make it happen (in ResourceFetcher::determineRevalidationPolicy):
  
    // Always use preloads.
    if (existingResource->isPreloaded())
        return Use;

However in determineRevalidationPolicy() method we return Reload earlier due to resource type mismatch:

    // If the same URL has been loaded as a different type, we need to reload.
    if (existingResource->getType() != type) {
        // FIXME: If existingResource is a Preload and the new type is LinkPrefetch
        // We really should discard the new prefetch since the preload has more
        // specific type information!  crbug.com/379893 
        // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case.
        WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to type mismatch.");
        return Reload;
    }

Here existingResource->getType() is Raw (or something else if as= is specified), while |type| for rel=import is always ImportResource.  (And we don't seem to have a good as= type for link rel=import cases: https://fetch.spec.whatwg.org/#concept-request-destination)

I'm not fully sure what the resolution should be, but probably we could do a few things:
- [spec] start a spec discussion on fetch spec to see if we want to have particular resource type for rel=import
- [impl] relax the type checking part in determineRevalidationPolicy() for preloaded resources for rel=import cases, at least if as= is not specified?


Comment 2 by kinuko@chromium.org, Apr 18 2016

Owner: y...@yoav.ws
Yoav, would you be able to take the initial look on this one?

(I'm going to share a repro site with you)

Comment 3 by y...@yoav.ws, Apr 18 2016

This seems to behave as intended (as you saw in determineRevalidationPolicy's code), since an import resource type shouldn't match link preloads with no `as` attribute. 

The right way to tackle this would be to add support for `as=document` [1] and define document to include both imports and frames.
Alternatively, if the former is not feasible, we'd need to define and add `as=import` or something similar. Unfortunately, previous attempts to define an `as` type for import hit resistance.

[1] https://bugs.chromium.org/p/chromium/issues/detail?id=593267

Comment 4 by kinuko@chromium.org, Apr 18 2016

Blockedon: 593267
Thanks for your quick update, reg: as=import I suspected that we might have made an attempt... thanks for the info.  So we'll need to start with spec discussion first?
 
Making this blocked by 593267 (or maybe this can be a dup of the issue)

Comment 5 by y...@yoav.ws, Apr 18 2016

I haven't yet given enough thought to see if `document` can cover both the frame and import use-cases. I need to dig further into that, since if it can work it can be the simplest route forward.
Cc: spelc...@chromium.org
Cc: tombergan@chromium.org
I think this is unrelated to as=import. I tried preloading a non-cacheable JS file (with the Link: rel=preload header, *without* the as attribute) and got the same issue (the script was preloaded then fetched again when the browser actually needed it). My reading of the spec is that this shouldn't happen (althought the spec seems to have a TODO about this point).

existingResource->getType() is Raw and type is Script.

In my test RawResource::canReuse also returned false because the header X-DevTools-Emulate-Network-Conditions-Client-Id didn't match (I had throttling on in dev-tools).

Comment 9 by kinuko@chromium.org, Apr 18 2016

#8 - the current code seems to suggest it happens for other subresource types too, while other types have work-around by adding appropriate as=.

Ilya, Yoav: do you think we should also make preload'ed resources generally usable by the main load when as= is not specified?  Sounds like we should?
Btw this is the reduced repro site we can test against (thanks Scott!):

https://opusjs.com/push-imports/

This pushes the subresources but yet Chrome loads the same resource again due to the problem described in this bug (i.e. the pushed stream is used by preload and another main load runs).

Comment 11 by y...@yoav.ws, Apr 19 2016

Cc: mkwst@chromium.org
Status: Assigned (was: Untriaged)
Kinuko: just to clarify, setting the appropriate `as` attribute (for all resource types) is not a workaround but the way the feature is intended to work AFAIUI. If `as` is not set, the preload is identical to XHR and should only match XHR requests.

Unless japhet@ or mkwst@ say it's perfectly safe (from CSP perspective and otherwise), I'd be very uncomfortable punching holes in the resource type matching algorithm for preload. It'd also break the "preload is a declarative fetch" paradigm, as fetch wouldn't enjoy the same "no need to match" privilege.

I think the right way to go here is to add proper support for all resource types.
Mike: thanks for chiming in. I wasn't fully sure if setting as= is the 'mandatory' thing to make preload work properly, and CSP and other security/safety thing was one of the biggest concern otherwise.  So looks like supporting it via as=document is surely the most plausible way to go.
Oops, sorry s/Mike/Yoav/ I got confused by the cc line..
My bad, rereading the spec, as= does seem mandatory. Apologies for the noise.
Cc: sorvell@chromium.org bmcquade@chromium.org kinuko@chromium.org ojan@chromium.org
 Issue 611253  has been merged into this issue.
Let me clarify our direction:
- add support for `as=document`, which is issue 593267, and
- let 'document' type include import cases too (in addition to frames)

(Yoav: please let us know if you need help / have any updates here- thanks!)

Comment 17 by y...@yoav.ws, May 13 2016

I'm hoping to tackle that in the next week or so.
Awesome, thanks!
Project Member

Comment 19 by sheriffbot@chromium.org, Jun 1 2016

Labels: -M-52 M-53 MovedFrom-52
Moving this nonessential bug to the next milestone.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 20 by sheriffbot@chromium.org, Jul 13 2016

Labels: -M-53 -Pri-1 M-54 MovedFrom-53 Pri-2
This issue is Pri-1 but has already been moved once. Lowering the priority and moving to the next milestone.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Comment 21 by y...@yoav.ws, Sep 7 2016

Blockedon: -593267
Cc: dglazkov@chromium.org
Summary: Add support for preloading <link rel=import> resources (was: Preloading subresource for <link rel=import> with no-cache ends up downloading the resource twice)
+dglazkov@

I think that the best way forward here is to define a proprietary `as` value for HTML imports, until we'll know where they're heading.
Components: Blink>Loader

Comment 23 by y...@yoav.ws, Jan 2 2017

Labels: -M-54 -MovedFrom-52 -MovedFrom-53

Comment 24 by y...@yoav.ws, Apr 10 2017

Owner: ----
Status: Available (was: Assigned)
There's a working patch to enable such support at https://codereview.chromium.org/2486193002

Due to the contention over the standardization of the "import" destination, I'm not planning to work on it in the near future.
Project Member

Comment 25 by sheriffbot@chromium.org, Apr 13 2018

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.

Sorry for the inconvenience if the bug really should have been left as Available.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Hotlist-Recharge-Cold
Status: Available (was: Untriaged)

Comment 27 by ojan@chromium.org, May 8 2018

Cc: -ojan@chromium.org

Sign in to add a comment