-
Notifications
You must be signed in to change notification settings - Fork 534
Network latency can cause css to block render in some cases. #19
Comments
Seems to work alright on 4G ;) |
I suggested earlier in the mail I send you yesterday the xhr method. I understand that we come across browser support complexities. So I understand the polling approach as well. I started thinking and came across http://stackoverflow.com/q/2635814. function loadCSS( href, before, media ){
"use strict";
// Arguments explained:
// `href` is the URL for your CSS file.
// `before` optionally defines the element we'll use as a reference for injecting our <link>
// By default, `before` uses the first <script> element in the page.
// However, since the order in which stylesheets are referenced matters, you might need a more specific location in your document.
// If so, pass a different reference element to the `before` argument and it'll insert before that instead
// note: `insertBefore` is used instead of `appendChild`, for safety re: http://www.paulirish.com/2011/surefire-dom-element-insertion/
var ss = window.document.createElement( "link" );
var ref = before || window.document.getElementsByTagName( "script" )[ 0 ];
var ssLength = window.document.styleSheets.length;
ss.rel = "stylesheet";
ss.href = href;
// temporarily, set media to something non-matching to ensure it'll fetch without blocking render
ss.media = "only x";
// inject link
ref.parentNode.insertBefore( ss, ref );
// This function sets the link's media back to `all` so that the stylesheet applies once it loads
// It is designed to loop until document.styleSheets includes
function toggleMedia(){
if(ss.sheet ){
ss.media = media || "all";
}
else {
setTimeout( toggleMedia );
}
}
toggleMedia();
return ss;
} In the link I pasted I see some if else, probably because |
Thanks @decrek. I like that, though I'd prefer something that came earlier than when the CSS finishes loading, since that'd be a great deal of polling. Regardless, I like the idea and will be poking at it a bit today. |
… in the CSSOM, and essentially loaded. This ensures that the sheet loads with a low-priority media query and the real media is set at a safe time. Fixes #19
Hi all. |
I tested this again with my insanely throttled connection and works(tested in Chrome) Btw I use Charles for that. Seriously I never been so deep into that cssom thing, so really don't know how that sheet property is supported. So I am curious about your testing results. AFAIK the href property is supported everywhere. I also see that in my proposal I poll until the stylesheet is loaded like you said in your reply and in your latest proposal you poll until it is present in the DOM (and started downloading?). That would be better. |
@decrek yes, that's the case (a non-applicable media type will be downloaded at a lower priority, async, in modern browsers). It seems that the This approach seems to work most broadly of those I've tested so far. |
@scottjehl Ah ok, that means the same amount of polling as in my proposal but better support than the sheet property. |
yeah, that’s what I’m thinking at least. On Oct 24, 2014, at 1:07 PM, Declan Rek notifications@github.com wrote:
|
This is merged now. @addyosmani I'd be interested in your thoughts on any better approach now that we have something workable at least. |
For posterity, the Probably worth testing on a Firefox phone, if anyone has one. |
I noticed this when testing over 3g. Sometimes, our timeout is fast enough to toggle the
link
'smedia
attribute toall
before its stylesheet request goes out, and it ends up blocking render. Not good.One workaround I've come up with so far involves polling the
document.styleSheets
array until it increments, which I've found is a safe time to toggle themedia
attribute on any connection speed, as the request appears to be in flight at the point it joins that array (yet it's still long beforeonload
, which is good for minimizing the times this logic would have to run). That change looks something like this:This works generally, but a downside to it is it may not work well with multiple
loadCSS
calls, since they'll all toggle their media as soon as the first call goes out. I think we might be able to work around this by queueing the media toggles in the order they're called. Maybe aloadCSS.locked
property would give us that sort of mechanism. The queue wouldn't incur much delay, since it's not about waiting for requests to return so much as ensuring the stylesheets have joined the CSSOM.Since it's high-priority, we'll try and close this one out in the morning.
The text was updated successfully, but these errors were encountered: