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

Hey Ben.

On Fri, Jan 12, 2018 at 9:26 PM, Ben Maurer <ben.maurer@gmail.com> wrote:
>
> 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.
>

I don't see why that would be the case.


> 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.
>

The fact that a resource was fetched with rel=preload is orthogonal to what
happens when and how a rel=stylesheet is executed. Consider the case when a
stylesheet is already in HTTP cache and you programmatically inject a
rel=stylesheet pointing to it: all same processing applies. If anything
rel=preload could actually *enable* better browser optimizations by doing
the CSS preparse ahead of time.


>  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.
>

It's a guarantee as far as HTML spec guarantees processing of the
particular type of resource. This has nothing to do with preload.



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

> 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.
>

I think you need to spell out "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.
>

Right, I see. I think that's a great use case to raise against HTML spec
and see what the guidance is there — this is not preload specific, same
applies for resources coming from HTTP cache, serviceworker, etc.

ig


> -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 06:15:46 UTC