How to stop a print stylesheet slowing down your web page

It might seem strange in a world of smartphones, tablets and progressive web apps, but people do sometimes still print web pages. And if you want your web page to be clear and easy to read on paper, you probably need to define some print-specific styles.

There are broadly two ways to do this. One is to use a single stylesheet that incorporates all your print and screen styles. Simply wrap your print-only styles in @media print { … } and your screen-only styles in @media screen { … }.

The other way is to create a separate stylesheet and give it a media type of print:

<link rel="stylesheet" media="print" href="myprintstyles.css">

The option you pick will depend at least in part on how many print-specific styles you use. If it’s a big number, you might not want them cluttering up your main stylesheet, and decide to create a separate file.

But there’s a problem.

Back in 2014, we ran some tests to find out if a print CSS file blocked rendering on screen (following similar experiments by Stoyan Stefanov in 2007 and 2012).

And it turns out that it could.

In other words, in some circumstances, the browser would paint no content to the screen until it had finished loading the print stylesheet.

This is less than ideal, especially on mobile, when you’re highly unlikely to be printing out content. It takes away what should be one of the main benefits of a separate print stylesheet.

Well, more than three years have passed since we last ran those tests, so we thought we’d see if things had changed.

Just like last time, we tested two pages. Both included a print stylesheet with a built-in delay of 15 seconds to load time.

On the first page, the print stylesheet was second object in the <head>, after a third-party CSS file, but before all other content, including the main CSS file, images and JavaScript.

On the second page, we tried putting the print CSS file at the end of the document, just before </html> (this used to be invalid HTML but, as we noted in a previous post, it looks like this will be legal in the latest versions of HTML5).

What we found

In Chrome, just like last time, everything worked exactly as we would want it to.

Both pages displayed without waiting for the slow stylesheet to load:

Internet Explorer didn’t do quite as well – putting the print stylesheet at the top blocked render start.

However, moving it to the bottom of the page allowed the page to display without waiting for the file to load.

Things were a little different in Firefox.

Again, the print stylesheet at the top of the page blocked render start. Again, the page was able to start displaying when the file was placed at the bottom of the document.

However, in both cases, the image on the page didn’t start to download until the slow stylesheet had finished loading.

So it looks as though a print CSS file – at least at the top of the page – could be bad news for performance. It means content is blocked by a resource that isn’t required to display that content.

However, while this is far from ideal, how big is the risk?

On the one hand, every blocking resource increases the risk of a delay. Even if it’s a relatively small file, it’s always possible that you’ll get the occasional slow response.

Then again, as we’ve just seen, a print CSS file isn’t blocking in Chrome, so there is at least some benefit in separating it out. And your print styles have to go somewhere, so are you really better off bloating your main CSS file?

Asynchronous CSS

One solution is to load the print CSS file asynchronously using Filament Group’s loadCSS – something we talked about in a previous post.

This uses preload to load CSS asynchronously in supporting browsers, falling back to a JavaScript polyfill for those that don’t.

This is effective across browsers:

The one caveat is that preload doesn’t work if you give the CSS file a media type of print.

So if you do use loadCSS to ensure that a print CSS file doesn’t block rendering, you just need to remove the media type from the file reference and wrap the contents of the file in @media print { … }.

It’s probably true to say that relatively few websites rely on extensive print-only styles. But if you do need to deliver content that works just as well on paper as it does on screen, then separating your print styles out and loading them asynchronously with loadCSS could be the way to go.

Published date:  29 January 2018

Written by:  Alex Painter

comments powered by Disqus

Filter By Service

Filter By Date