-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loading CSS asynchronously without FoUC #195
Comments
Thanks for writing up this alternative to consider, @noamr. There's a lot to address here and I am sorry it'll be a little long. I wrote an answer a few different ways before deciding it'd be easiest to talk about the pros and cons of the existing solution we already have today, and then getting into why I feel this new proposal falls short of the pattern we already have. I'll end with the (perhaps unsurprising) recommendation that I feel is most flexible and intuitive. Existing Solution BenefitsAs the prior issue notes, we have a long-standing pattern that is relatively well-known for loading a stylesheet asynchronously, and it gives authors a tool to address every use case described in the prior issue. That pattern is this one, known as the print media hack:
To give an example, authors can already use this workaround for "styling elements into existence," and they can do so without any concerns for a Flash of Unstyled Content (FOUC). Reusing the help widget example from above, this works great today:
Let's highlight some benefits of this existing pattern:
Existing Solution DrawbacksThe print-media workaround addresses all use cases well, but it has the following problems:
In summary, the drawbacks of the existing workaround have nothing to do with how it works. The problem is mostly just that it's not documented and intuitive as a standard. Drawbacks of the new proposals in this issueThis issue proposes two means of triggering an asynchronous stylesheet request:
In all, these proposals are not as flexible or intuitive as the approach below: Recommended Standardization ApproachBased on the benefits and drawbacks outlined above, standardizing the behavior authors already use via the "print media" workaround is the most flexible, intuitive option we have:
Thanks so much! |
This is not true; authors have to take steps like specifying |
[edit: sorry, my earlier reply had email formatting garbage!]
@zcorpan I agree that the media-print workaround itself doesn’t coordinate to hide any elements initially without having some styles in the page already. (I think that’s a good thing. If it did, it would be catering to one parent-element display use case and would limit its flexibility to be used for purposes like those listed above).
In that section you quoted, I meant that the workaround pattern as shown not only ~works~, but it’s a reasonable and intuitive way to set this pattern up: it’s common to have some CSS apply to an element initially (whether that CSS lives in a typical external stylesheet or inline), and then another stylesheet overrides those styles.
I don’t agree that further design (eg new hidden attr behavior, link-in-body requirements , etc) is needed to support these patterns other than making the triggering attribute more obvious to authors and in parity with script.
Thanks!
|
I see this as a bug and not a feature, It is very FoUC-risky if not done by an expert.
If you're loading the widget via script, you can also load its style into
It handles both these use cases poorly, unless done by an expert. Experts can already achieve this with JS. As per the last WHATWG meeting, we are not going to make something "more intuitive" that requires expertise to achieve without FoUCs and already has a JS way of achieving.
For 1, 2 & 4 above: you can also
In this whole writeup you ignore the drawbacks of the current solution, which is that without expertise it would create a FoUC. This makes your argument incomplete. Note that we have these problems in the field today with |
My understanding and experience is that |
No worries, it's too late to remove it:) |
Just to establish a baseline for the discussion, how might one compartmentalize There might be some middle ground here that mixes the two approaches:
I’m fine with the above but I wouldn’t consider it (or Are we saying that something like
|
We can structure it like this, but we'd need to solve the scoping problem. We could say that whenever This would be similar to the following, which would also work bundling-wise:
the stylesheet would be loaded twice, but only parts of it would be used.
|
It’s giving |
Yea but |
Introduction
The following user paint points existed for a long period of time in the web:
This has been tricky for web developers to tackle, as often solving one of these can damage the other. For example, loading all the styles asynchronously would load the page faster, but would lead to more FoUCs. Web developers are currently able to achieve this effect, albeit by using scripts (changing the
rel
ormedia
on the link element'sload
handler).whatwg/html#3983 shows a long conversation about this topic.
The crux of the problem is that in the majority of cases, CSS is imperative for correctly displaying the content that relies on it. So loading it asynchronously is almost guaranteed to result in a FoUC.
However, there are certain use cases to loading CSS asynchronously that are worth exploring.
Use Cases
Style into existence
A common and valid use case for asynchronously loading stylesheets is for elements that are hidden by default, but the existence of the asynchronously loading style would change that and display them:
In this case, the help widget would appear at some time in the future, when
help-widget.css
is loaded. This would not be a FoUC.Font-swap
Font loading is a pain point for performance optimization across the web. One common technique today is "swapping" - displaying a local font, and swapping it with a heavy web-font once loaded:
This works, however usually the CSS that loads the font is remotely-loaded by itself, so we might be render-blocked before we even know that we have a swappable fonts.
Goals (Optional)
This would be successful if it provides one or more solutions to the above use cases (or to other similar use cases), that makes it more ergonomic and less error prone to develop and load efficiently, without adding to the risk of FoUC.
Non-goals (Optional)
A generic "async CSS without scripting" solution is a non-goal. HTML should be opinionated about preventing FoUC by default, and expert approaches that can cause FoUC can remain in JS-land.
Proposed Solution
Proposing to treat the "style-into-existence" and "font swap" problems as separate ones.
"Hidden until resources loaded"
Make it easier for developers to use this technique without requiring script, e.g.
In the above example, the
help.css
stylesheet would not block the parser, or anything outside of#help-widget
, but#help-widget
would remain hidden until it is loaded (+ async scripts). We'd have to make it so that styles loaded this way are scoped, which should be doable with nesting.Font stylesheet
It is a valid use case to asynchronously load stylesheets with
@font-face
descriptor that swap fonts. Perhaps we can allow that?The above link would be downloaded asynchronously, but would only parse font-descriptors from the stylesheet.
It's backwards-compatible as it would behave like a regular stylesheet on browsers that don't support it.
Examples (Recommended)
See above.
Privacy & Security Considerations
(TBD, a bit early)
Let’s Discuss
The text was updated successfully, but these errors were encountered: