W3C home > Mailing lists > Public > public-web-perf@w3.org > January 2018

Re: Using preload for "async" CSS by changing `rel` trick

From: Ben Maurer <ben.maurer@gmail.com>
Date: Fri, 12 Jan 2018 21:26:36 -0800
Message-ID: <CABgOVa+YORaFtubW+N=omuiRoDM5mBySLyQVZCX4F7pA+4eLHA@mail.gmail.com>
To: Ilya Grigorik <igrigorik@google.com>
Cc: Philip Walton <philipwalton@google.com>, Royi Hagigi <royi@fb.com>, "public-web-perf@w3.org" <public-web-perf@w3.org>
Hey Ilya,

I could have sworn that in some of the discussions we had around
rel=preload there was concern that making this kind of synchronous
guarantee might prevent browser optimizations. As an example, imagine that
a browser decided to make the parsing of CSS happen off the main thread.
The browser might not be ready to immediately apply the style even though
it had been downloaded. Similarly it seems reasonable that if a browser had
downloaded a javascript file using rel=preload that it might not be able to
synchronously run it if inserted into the dom because it might have to
parse it off the main thread.

If this is in fact a guarantee, I think it'd be great to clarify it in the
spec and ensure there are proper tests.

-b

On Fri, Jan 12, 2018 at 9:07 PM, Ilya Grigorik <igrigorik@google.com> wrote:

>
>
> On Tue, Jan 2, 2018 at 9:40 AM, Royi Hagigi <royi@fb.com> wrote:
>
>> There is a trick floating around to use `<link rel="preload"
>> href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">`
>> to load CSS “async” similar to how async scripts are loaded. (Details at
>> https://github.com/filamentgroup/loadCSS). This definitely works (at
>> least in Chrome) but I have a couple questions…
>>
>>
>>
>>    1. What are your thoughts on doing this? I see some discussion years
>>    ago about the value of an “async” attribute like on <script> tags but for
>>    stylesheets, but not too much discussion recently. It seems like a bit of a
>>    hack and feels like the behavior might not be predictable, even if it works
>>    right now.
>>
>> Why or how is this not predictable, and why would it break in the future?
> The intent of preload is to decouple fetch from execution, and this
> particular pattern just happens to run the execution immediately after the
> fetch completes. Alternatively, one could defer the execution until some
> (arbitrary) later point — e.g. to avoid or minimize FOUC, to apply multiple
> resources at once, etc. Which is to say, there is nothing "wrong" with this
> pattern; everything is working as expected.
>
>
>>
>>    1. The spec isn’t clear about what would happen here if you change
>>    the “rel” attribute of the link, and I’m not sure what the behavior would
>>    be in latest Chrome for example.
>>
>> Change from, to? Preload spec defines behavior of rel=preload. If you
> change rel to some other valid type
> <https://html.spec.whatwg.org/#linkTypes>, the processing defined by HTML
> standard kicks in.
>
>
>>
>>    1. Should it be guaranteed that the stylesheet is installed in the
>>    page in the same frame as the `“onload=”this.rel=’stylesheet’”` is
>>    fired?
>>
>> Yes. This is as defined by HTML spec.
>
>
>> Example: you have JS that renders a part of your page on the client, but
>> in order to avoid FOUC, needs to wait for this stylesheet that is being
>> loaded this way. If the JS listens to the preload link’s “onload” event and
>> renders to the DOM in the same frame as “rel” is set to stylesheet, will
>> the styles be applied to the page when the new markup is shown or is there
>> a chance the browser will defer applying the stylesheet to later, causing a
>> FOUC?
>>
> https://html.spec.whatwg.org/#link-type-stylesheet: see "Once a resource
> has been obtained.. " step. tl;dr: the browser should apply it immediately.
>
>
> On Sat, Jan 6, 2018 at 11:21 AM, Philip Walton <philipwalton@google.com>
> wrote:
>>
>> Does anyone on this list have context for if/whether there were issues
>> with async stylesheets that prevented them from going forward?
>>
>
> There are no issues with it per se.. Within this group we prioritized work
> on preload because it provides a more flexible and powerful low-level
> primitive that can be used to implement and explain <style async>.
>
> ig
>
>
>
>> On Tue, Jan 2, 2018 at 9:40 AM, Royi Hagigi <royi@fb.com> wrote:
>>
>>> There is a trick floating around to use `<link rel="preload"
>>> href="path/to/mystylesheet.css" as="style"
>>> onload="this.rel='stylesheet'">` to load CSS “async” similar to how
>>> async scripts are loaded. (Details at https://github.com/filamentgro
>>> up/loadCSS). This definitely works (at least in Chrome) but I have a
>>> couple questions…
>>>
>>>
>>>
>>>    1. What are your thoughts on doing this? I see some discussion years
>>>    ago about the value of an “async” attribute like on <script> tags but for
>>>    stylesheets, but not too much discussion recently. It seems like a bit of a
>>>    hack and feels like the behavior might not be predictable, even if it works
>>>    right now.
>>>
>>>
>>>
>>>    1. The spec isn’t clear about what would happen here if you change
>>>    the “rel” attribute of the link, and I’m not sure what the behavior would
>>>    be in latest Chrome for example. Should it be guaranteed that the
>>>    stylesheet is installed in the page in the same frame as the
>>>    `“onload=”this.rel=’stylesheet’”` is fired?
>>>
>>>
>>>
>>> Example: you have JS that renders a part of your page on the client, but
>>> in order to avoid FOUC, needs to wait for this stylesheet that is being
>>> loaded this way. If the JS listens to the preload link’s “onload” event and
>>> renders to the DOM in the same frame as “rel” is set to stylesheet, will
>>> the styles be applied to the page when the new markup is shown or is there
>>> a chance the browser will defer applying the stylesheet to later, causing a
>>> FOUC?
>>>
>>>
>>>
>>> Thanks, and hopefully I provided enough context here,
>>>
>>>
>>>
>>> Royi Hagigi
>>>
>>> royi@fb.com
>>>
>>>
>>>
>>
>>
>
Received on Saturday, 13 January 2018 05:28:01 UTC

This archive was generated by hypermail 2.3.1 : Saturday, 13 January 2018 05:28:02 UTC