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:30:45 -0800
Message-ID: <CABgOVaJA5bZk=aZUm6=LtH+bH7gijzYArSDvtw2B1uvZtf6A9w@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>
To further clarify -- I totally understand that rel=preload will ensure the
file is downloaded and in the browser's cache. The reason I suggested Royi
email the mailing list is because in the system Facebook has, it's
important that we know the resource in question is immediately available.
We use the fact that a resource has been downloaded to reveal content that
depends on the JS/CSS that we are fetching. So if rel=preload told use
a.css is available we'll insert HTML that uses a.css into the DOM. Even a
single frame of the browser doing something like parsing the file would
create a disruptive user experience.

-b

On Fri, Jan 12, 2018 at 9:26 PM, Ben Maurer <ben.maurer@gmail.com> wrote:

> 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/filament
>>> group/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:31:08 UTC

This archive was generated by hypermail 2.3.1 : Saturday, 13 January 2018 05:31:08 UTC