-
Notifications
You must be signed in to change notification settings - Fork 532
Experiment with how to use loadCSS to polyfill link[rel=preload] #59
Comments
On first pass, yeah, I think that looks correct. /cc @yoavweiss |
thanks @igrigorik :) ...was there an alternative way you were thinking it could be enabled if not the rel toggle? |
Assuming that works, what you have is much better (terser) than I had in mind for this particular case. So, no.. That said, for more complicated cases, where you may want to delay the stylesheet until later, or block it on other fetches, you'd probably want to use an external function, etc. |
What you have now LGTM. |
That's pretty cool. Although I'd still like the blocking solution so I can do something like: <style>/* inlined css */</style>
content content content
<link rel="stylesheet" href="css-for-next-bit-of-content">
content content content
<link rel="stylesheet" href="more-css-for-next-bit-of-content">
content content content
footer And have the browser take care of render-blocking for me. |
@jakearchibald I think that approach is a really interesting idea but it leaves me with some questions about how it would work:
Thanks @jakearchibald ! |
Thanks @igrigorik. Allowing Maybe my questions can be summarized with this: In what conditions would it make sense for a developer to place blocking |
Can you provide some examples? My feeling was, although the inlined CSS may be able to render parts of below-the-fold, it'll often lead to the page jumping around as the additional CSS loads. You can avoid this by guarding against it with extra CSS, and you should be able to do that with a truly async stylesheet, but I figured it'd be too complex for the default.
I don't think it's "another" point of failure, as it already is. The current state for
It's down to the page to decide what's first-render critical, rather than a page module. A single page module may be critical on one page, but secondary on another. Does a fully async stylesheet change the pattern here?
I don't think that's a great assumption unless you're in full control of the cache (eg ServiceWorker). Stuff falls out of the cache all the time, way more frequently than cookies for instance. Can you talk me a bit more through what you load inline and what you load async, and what the rendering looks like in between? I don't think I've got the right mental model of the problem. I saw it like this: <style>/* inlined css */</style>
CONTENT SET 1
<link rel="stylesheet" href="css-for-next-bit-of-content">
CONTENT SET 2
<link rel="stylesheet" href="more-css-for-next-bit-of-content">
CONTENT SET 3
footer For the uncached load, you'd inline the CSS for Transitioning to HTTP/2, you'd switch the inline css for a normal For a social media stream, it may be more like this: <style>/* inlined css */</style>
<link rel="stylesheet" href="feed-extras" async>
<div class="main-feed">
<article>
CONTENT
<div class="buttons-etc"></div>
</article>
</div>
<link rel="stylesheet" href="secondary">
<div class="secondary"></div>
<link rel="stylesheet" href="tertiary">
<div class="tertiary"></div> On desktop, secondary & tertiary may be left & right columns. So the inline CSS would get you the content of the feed. I guess the pattern here is that particular modules have the capability to fast-load, meaning they inline the essentials, but it's down to the parent module (or page) to decide if they should use that mode for that layout. |
Hmm, maybe I'm wrong, but I feel that the rendering on the right is broken and should be avoided. If the user sees it jump from that to the correct rendering, that further confirms to them that the initial render was broken. |
Hey @jakearchibald. Thanks for the feedback :) I definitely agree with you that the layout on the right is incomplete. I just think it's preferable to show content that isn't fully rendered instead of showing nothing at all. If there's a short time after which a browser will stop blocking rendering and show the content following a As a parallel example, it seems like folks have come to an agreement that hiding text for more than a few seconds while custom fonts load is not in our users' best interests. A progressive render in that case, and I think maybe in this case too, seems preferable to showing nothing. All that said, I'm starting to wonder if an ideal first-approach to "critical css" inlining is to try to capture all CSS necessary for a view, rather than just for the "above fold" portion. Then the async fetch is merely for caching CSS for the next view. Mileage would vary though... |
Oh - your points about the transition to http2 are great. And the part about the cookie & cache: yeah... hrm. I love the idea about improving that with service worker. In absense of that, it has seemed like a worthwhile assumption, since it often works as we'd prefer, and in the case that it doesn't, the user ends up with a blocking CSS reference, which I'd consider more "unoptimized" than "broken" at least. |
I'm not so sure, but I don't have any evidence. I take your point about fonts, but I still think a late font switch is a poor experience. I really like the font rendering proposal, as I can have an early fallback, but disable a switch after that.
That's what I did for SVGOMG, I think it works well for low-content "apps" that have most of their complexity an interaction away. With https://wiki-offline.herokuapp.com/wiki/Hulk_Hogan I load the CSS for the article async, but hide the article element until it loads. Can't decide if this is the right approach though (in this case the CSS tends to load before the article content). |
Btw, I haven't done a test to see how inlining compares to HTTP/2 push. A lot of assumption on my part. |
Yeah. We've been going under the assumption that a lot of these workarounds will be unnecessary with Push, but I guess as long as we're serving HTTP1, it's nice to make it as fast as we can. thanks! |
@scottjehl @jakearchibald note that the "scenario on the right" (#59 (comment)) is the behavior you get today in FF and IE: https://www.w3.org/Bugs/Public/show_bug.cgi?id=27303#c27 - not saying it's correct though.. I agree with Jake, I'd prefer to avoid flashing unstyled content. The proposal in the linked bug is to have a safe(r) in-between. That said, if we can't get agreement on that, I'm wondering if we should change Chrome to use FF/IE's strategy. /cc @pmeenan |
@igrigorik is there an updated approach to detecting |
Still open: w3c/preload#7 |
ah yes, sorry. thanks @yoavweiss |
Looks like this will be relevant to our interests here https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/xEoWkGEd_g4/Pkn_o92EAwAJ |
@scottjehl <link rel="preload" href="asnyc.css" as="stylesheet" onload="this.rel='stylesheet'"> Does not work in Chrome canary (49.0.2623.0 canary (64-bit)), although it supports I actually very like the idea of blocking below the <link rel="stylesheet" href="module-a.css" once>
<div class="module-a">
<!-- .... -->
</div>
<link rel="stylesheet" href="module-b.css" once>
<script src="module-b.js" once async></script>
<div class="module-b">
<!-- .... -->
</div>
<link rel="stylesheet" href="module-c.css" once>
<div class="module-c">
<!-- .... -->
</div>
<link rel="stylesheet" href="module-b.css" once>
<script src="module-b.js" once async></script>
<div class="module-b">
<!-- .... -->
</div> |
Regarding preload's onload event, it is a bug. Fix is at https://codereview.chromium.org/1586563014/ and I hope to land it very soon |
@yoavweiss |
Now that Canary's support is testable, there's a workflow script and example for this in master now. |
Uuuuh nice. Can't wait! |
onload="this.rel='stylesheet'" good ~ |
Hi tanks for your work, It works great on Pagespeed desktop but it doesn't seem to work for mobile as i still get the error message on PageSpeed Insight, is is a google bug? |
In the following demo page I've referenced a slow-loading CSS file with
link[rel=preload]
and polyfilled its request usingloadCSS
if a feature test forpreload
fails. _(Note: the slow-responding CSS file is not critical to this test, but it's useful for visually observing whether or not the CSS request blocks rendering across our test pages).It works, but I'm unsure whether the syntax and logic lines up with how this feature is intended to work.
http://filamentgroup.github.io/loadCSS/test/preload.html
The text was updated successfully, but these errors were encountered: