Hello.

This is a proposal for an addition to the LINK element spec that includes a 
recommendation for deferring the load of inapplicable stylesheets until later 
in the load process (thus not blocking page rendering for unnecessary styles).

Some background:

CSS referenced by link elements or @import has always come with the limitation 
that it will block page rendering until it has finished loading. In many cases, 
there's good reason for this behavior, as the alternative - simply letting the 
page render independently of stylesheet requests -- almost always results in a 
flash of unstyled content. However, the downside of this behavior is that ALL 
CSS, not just the CSS that will apply to the particular device and viewport at 
the time of page load, will block page rendering. This means that sites that 
use CSS3 media queries to deliver different styles to different browsing 
conditions will be delivering more and more overhead.

Recently, I did some research into how browsers request CSS files via link 
elements with inapplicable media queries. The results were grim. Of all 
browsers that I tested, every one would not only request all CSS files 
referenced with inapplicable media types/queries, but they would also block the 
rendering of page content until all of those inapplicable styles were loaded.

Here's the test page including a table with the test results:
http://scottjehl.github.com/CSS-Download-Tests/


Proposal for change:

I'd like to propose that the spec recommends that vendors defer the loading of 
Stylesheets referenced via inapplicable media so that they do not block page 
rendering. These stylesheets should probably still be requested asynchronously 
so that they are present in the event that their media becomes active (say, 
after a browser resize or orientation change), but loading them up-front slows 
down the user experience unnecessarily.


Example implementation of proposed behavior:

Following the research above, I created a JavaScript utility that causes 
browsers to load CSS in a blocking or asynchronous manner, depending on their 
need at load time. I'm not a fan of using JavaScript to do something like this 
unless we have to, but for the time being, I think it illustrates the 
advantages of the proposed behavior. The project readme explains further and 
includes demo files that log information about what files where loaded, and 
how, depending on device and viewport conditions: 
https://github.com/scottjehl/eCSSential#readme

One very common case that this unfortunately can never solve is preventing the 
request of inapplicable styles that are concatenated into a single CSS file. 
The workaround above addresses this scenario though, and if link fetching 
behavior was improved in the ways suggested above, a workaround that works with 
concatenated files would at least be easier to produce.


-- FURTHER SUGGESTIONS --

1. Entirely preventing the request of stylesheets that may never apply

It would be ideal if a device could completely restrict the download of 
stylesheets that it determines could never apply within its environment. For 
example, if a stylesheet is referenced using a (min-width: 1000px) media query, 
a small-screen device could decide that this stylesheet should not be fetched 
at all because it could never apply on its screen dimensions.  This is actually 
the default behavior implemented by the eCSSential workaround above for min and 
max height/width queries. It merely re-evaluates if an inapplicable query would 
apply if it were a "device" query instead of a viewport query, and if not, the 
stylesheet is not loaded at all. 

The savings in HTTP weight and request counts as a result of this change can be 
very significant on a small screen. Of course, this behavior runs the risk of 
not having a stylesheet on-hand when the browser is moved to another screen. 

With this edge case in mind, it would be ideal if stylesheets that could not 
apply on a particular device are ONLY requested in the event that their media 
conditions become true. In other words, if device conditions changed to make a 
media query apply, such as moving the browser window to another screen, the 
necessary stylesheets would be requested at that time.



2. Reducing the amount of time that an unresponsive stylesheet can block page 
rendering

One last suggestion. In the research above, I found that many modern browsers 
will prevent page rendering for upwards of 30 seconds (sometimes more) to 
ensure that all stylesheets have loaded. If a server is not responding for some 
reason, this results in a completely unusable experience.

I'd like to propose that the spec recommends that stylesheets be given a 
timeout of a much lower maximum before rendering the page in whatever state it 
happens to be in. Ideally, the responsive requests would be left open or 
restarted so that they're given a chance to load and apply after the content is 
shown, but they should not block page rendering after that timeout.


Thanks!

Thank you so much for your time and consideration in these ideas. 
If you'd like me to split them into separate emails, or even direct them to a 
different working group, I'd be happy to do so.

Scott Jehl

Filament Group, Inc.  |  scottjehl.com  |  Twitter: @scottjehl



















Reply via email to