Delay loading your print CSS

So you have two stylesheets on your page, like this:

<link type="text/css" rel="stylesheet" href="screen.css"
      media="screen" />
<link type="text/css" rel="stylesheet" href="print.css"
      media="print" />

The first one is used to render the page on screen, the other one is used for printing the page and print previewing it. Good.

The thing is, when it comes to performance, the browser won't render any part of the page, until all stylesheets are downloaded (fiddled with here). That includes, unfortunately, stylesheets not designed for the currently rendered media. In other words, the browser won't display your page, until the print stylesheet is also downloaded, although it's not used at all for displaying the page. That sucks and should really be addressed in future browser versions.

Test

I did a test page to check this, it's here - print.php. It includes two stylesheets, the first one intentionally sleep()s for 5 seconds, the second one - for 10 seconds.

The result is that in both Firefox and IE it takes 15 seconds for this page to be rendered. Here's the Firebug picture:

media-print.png

In Safari on Windows, it only took 10 seconds the first time around, as both stylesheets were downloaded simultaneously. Good. The bad is that after refresh, the first CSS was not even requested, I tried it a few times, actually sometimes I got the error "The error was: “unknown error” ((null):10053) ", but hey, this is the first release of the browser, it can't be perfect. Actually after I shut down Fiddler, which is what I used to monitor the HTTP traffic, the page was back to normal, so it's not clear who's to blame.

So?

Well, in order to increase rendering performance, all stylesheets not absolutely needed to initially render a page should be loaded after the page load, in the background. Once the user has a fast rendered page to interact with, you can load the additional CSS (and JavaScripts for that matter) in the background, using script and style DOM includes.

Update: From my comment bellow - a better option is to include the print css as part of the main css:
@media print {…}


Post this entry to: » del.icio.us  » Digg  » Furl  » Newsvine  » reddit  » Y!

Somewhat related posts

20 Responses to “Delay loading your print CSS”

  1. Scott Says:

    Interesting idea but wouldn't this prevent non-javascript devices from using the print style sheet?

  2. Michael Says:

    @Scott: Perhaps you could include a noscript section…?

    You could also have an SWF loaded into an object section that writes Javascript to the page that pulls the print stylesheet into the page flow…

    :)

  3. Nathan Rutman Says:

    This sounds a little backwards to me. I'm not sure we should add this kind of complexity to save a few k in downloads. Requiring Flash or JavaScript in order for the print CSS to work adds requirements to the user environment for what is probably minimal gains in performance.

    Can I ask how this idea was sparked? Did you have a real life scenario that made this worth investigating?

    Interesting, but I'm not sure it's useful.

  4. Sergio Jardim Says:

    I agree with Nathan. Usually the print stylesheet only takes a few extra bytes.

  5. Stoyan Says:

    Thanks for the constructive comments!

    @Nathan - There was no real-life scenario, just a quest for understanding how to build high-performance pages.

    @Michel - I guess the only thing you can do to make it more complicated is to have a javascript that makes an AJAX request to get contents for another script that generates the OBJECT tag on the fly :)

    @Scott - You're right. The other option (and probably the best) is to include the print styles in the main CSS document with @media print {…}

    The question was not to save a few Kb, because you end up downloading the file anyway, only delayed in the background. The question was to decrease the number of HTTP requests during the initial load, since those are the most expensive. The thing in this case is that you have network latency and you never know how long it could take to download 1k css file. During this time users don't see anything and the whole page seems slow to them. There were stats somewhere showing what percentage of the users will abandon the site for every second delay in loading. It's just unfortunate to lose visitors when you page is fully loaded, but not rendered because the browser is waiting for one more css file which is not immediately needed.

  6. Peter Daams Says:

    Interesting point. 1 kb may not be much on a per-page situation, but if you get a million visitors a month, that's 1 GB of wasted bandwidth right there. Still not a huge amount for a large website, but nonetheless something worth investigating. Relying on js doesn't seem great to me either, for the reasons already mentioned + the extra bandwidth + processing time required. Browsers should really be the ones offering a solution.

  7. Tim Hofman Says:

    It's a creative idea, but it really hurts the accessibility of your page.

    If for some reason JS is unavailable, the browser won't be able to use the print stylesheet. As a result you can only print the page including the navigation, banners etc…stuff you really don't want to find back on your printed document.

  8. Jon Says:

    Thanks for the info, it's fun to figure these things out even if there isn't an "extreme" real-world need!
    But it's an interesting read none-the-less… :-D

  9. Jason Says:

    hmmm, interesting discovery.

    Like everyone else has said, is this something really to fret about?
    The print style sheet should definitely be no bigger than a few bytes. After the first page load the styles should be cached by default reducing the load on the server. So even with this problem you are only talking about shaving off a few milliseconds on the initial load.

    I did a quick search on google about possibly importing the css through javascript but came across this informative article instead:
    http://www.sitepoint.com/blogs/2007/04/10/faster-page-loads-bundle-your-css-and-javascript/

  10. Onipresente » Blog Archive » Delay no CSS Says:

    […] Neste simples tutorial ensina como fazer. A técnica é simples. Ele simplesmente insere um script PHP no código CSS. Através da função sleep do PHP, browser pára a exibição do conteúdo, enquanto isso o css é carregado. Simples, não? […]

  11. Max Design - standards based web design, development and training » Some links for light reading (20/6/07) Says:

    […] Delay loading your print CSS […]

  12. sassospicco Says:

    It doesn't happend in Opera (I'm using Opera 9.21)

  13. graste Says:

    In Opera the content is usually displayed earlier (even instantly if you want to). About 2 seconds after refresh the table is displayed unstyled, after 6 seconds the styles are applied, after about 11 seconds the page has finished loading.

    In the 'preferences' (ctrl-f12) under 'advanced->browsing->loading' you can set the time, when Opera should redraw the content. In my version it is set to 'redraw after 1 second'. If I set it to 5 seconds, the table content appears first after about 5 seconds (unstyled of course) and gets its styling not a second later (because of your delay).

  14. Punb Says:

    I agree with Peter that browsers should not grab the print style sheet until the user tries to print or does a print preview, then it should grab it and cache it.

  15. df Says:

    @Peter
    Yeah, it would be great if the browsers did not get the print css until someone prints. You might put the print style on your site, not because many people print, but because it saves a few people ink.

  16. tv Says:

    Actually, didn't everyone miss the obvious solution? Simply set up a hidden frame to load the print-only version of the CSS file. Maybe even an iframe at the very bottom would work, and style it to not display or even be visible. Since the main content will load simultaneously with the frame it should all work just fine. Haven't tried it cuz I don't need that, but I bet it will be good. :)

  17. Media attribute - what have you done for me lately? - Friendly Bit Says:

    […] You could think that the browser only loads the one stylesheet that matches the media it’s currently showing. Not true. All stylesheets, no matter what media they are tied to, are loaded at startup. […]

  18. mcdave.net » links for 2007-12-31 Says:

    […] phpied.com » Blog Archive » Delay loading your print CSS (tags: css performance development) […]

  19. Web Development 2.0 » Blog Archive » Media attribute - what have you done for me lately? Says:

    […] You could think that the browser only loads the one stylesheet that matches the media it’s currently showing. Not true. All stylesheets, no matter what media they are tied to, are loaded at startup. […]

Leave a Reply