CSS files downloaded twice in Internet Explorer with protocol relative URLs

I think we can all agree that performance of web sites matters a lot, and slow web sites are very annoying both for developers and, more importantly, end users. Therefore, we need to talk about a newly discovered problem: Internet Explorer, protocols and inclusion of stylesheets.

Steve Souders, web performance guru and all-around top bloke, writes in Missing schema double download about a performance issue. Apparently, as it turns out, when you include CSS file with the link element or @import statements, there’s a risk that the same file will be downloaded twice in Internet Explorer. Yes you read that right: twice!

The downside of this is of course multiple HTTP requests for just one file (and the latency, superfluous header info etc to go with that) and downloading double the size in kilobytes for CSS code; same file, not read from cache at all. The problem lies in using protocol relative paths to your CSS file(s), like this:

<link href="//example.com/css/base.css" type="text/css" rel="stylesheet">

That code will start at the root of the web site and from there look for a catalog named css and then a file named base.css in it. Where it fails in Internet Explorer, though, is that this asset will be downloaded twice.

Recommended ways to get around this problem is to use an absolute, root relative or location relative path to your CSS files, like this:

<link href="/css/base.css" type="text/css" rel="stylesheet">

or

<link href="http://example.com/css/base.css" type="text/css" rel="stylesheet">

or

<link href="../css/base.css" type="text/css" rel="stylesheet">

This could suck in the perspective of flexibility (e.g. different environments, mixed http and https protocols etc), but at the same time, if there’s anything you can do to make things faster in the web browser that is already far slower than the others, you should do it.

Post updated with corrections, where I had misunderstood parts in the original version

20 Comments

  • Robert, are you sure of this? Did you do any additional research after reading Steve’s post?

    I'm asking because you based this blog entry on Steve’s post, and he only talks about protocol-relative links. He doesn't mention root-relative links.

    To clarify, Steve says: <code><link href="//css/base.css" type="text/css" rel="stylesheet"></code> will (sadly) cause <code>base.css</code> to be downloaded twice in IE.

    Root-relative links like <code><link href="/css/base.css" type="text/css" rel="stylesheet"></code> should work just fine.

  • Markus says:

    It seems that the double download only occurs when the css url is protocol realtive like <code>//example.com/css/base.css</code> not when it is root relative like <code>/css/base.css</code>

  • Florent V. says:

    Robert, it looks like you got it wrong. Steve Souders doesn't write that page-relative paths (e.g. "some/path/to/file.css") or domain-relative paths (e.g. "/assets/some/path/to/file.css") trigger this bug. He writes that protocol-relative URLs (e.g. "//example.org/assets/some/path/to/file.css") trigger this bug in IE7-8.

    (Note that I'm making up the page-relative, domain-relative and protocol-relative adjectives. Not sure how these patterns should be called.)

    Using an almost-full URL with a missing (implicit) protocol is not a very common pattern. The use case Steve writes about is when the same content can be served as either http or https, and you want to avoid linking to http ressources from a https page.

  • Robert Nyman says:

    Mathis, Markus, Florent,

    Thanks guys! Apparently I was a bit trigger-happy and didn't read between the lines (in a comment to his own post, Steve says that root relative URLs aren't affected, but it's not totally clear in the post).

    So, still an issue, but not near as big as it could have been.

    That's the good thing about blogging about it and allowing for comments, though. ๐Ÿ™‚

  • Are you sure? When I read Steves article, I get a feeling this only affects sites which uses protocol relative URLs, e.g. URLS starting with double slash: //css/base.css.

    I haven't seen any waterfall charts myself though.

  • Robert Nyman says:

    Anders,

    Missed me by a minute. ๐Ÿ™‚

    The post is now corrected.

  • Trygve Lie says:

    One should also note that there is a issue with double requests in IE if one move a script tag around in DOM. In large traffic websites this can have huge performance issues on the server side since the server get hit more than it should.

    I discovered this during debugging a Ad system some time ago and wrote a small article on the problem and how to avoid it.

  • Florent V. says:

    I'm not sure about the "//css/base.css" example. From my very quick tests with Firebug, it seems that the browser (well, Firefox at least) will understand // as a protocol//domain separator.

    A website of mine uses this path:

    /public/css/all.css

    If I write it with a double as //public/css/all.css, it doesn't work anymore. I think Firefox then sees "public" as the domain name (since intranet or local domains don't have a TLD).

    This works fine:

    //covertprestige.info/public/css/all.css

    And if I had more slashes between the domain and the path, Firefox resolves the multiple slashes as just one, so it works as well:

    //covertprestige.info//////////public/css/all.css

    (I even tried with one hundred slashes, still works. Simple regexp is simple?)

    So, hum, my point is that maybe "//example.org/css/base.css" would be a better example for your post. Thoughts?

  • Olov says:

    "The only way to get around this problem is to use an absolute or root relative path to your CSS files"

    Is that really correct? As I understand it only a missing schema will trigger this, so location relative link <code><link href="../css/base.css" type="text/css" rel="stylesheet"></code> won't make it download twice. Or?

  • Florent V. says:

    + Same question as Olov.

  • Robert Nyman says:

    Florent,

    I seem to get the same results, under the same circumstances, so I have updated the post with the suggested better example. Thanks!

    Olov,

    I agree about the formulation, and from what I've seen location relative seem to work as expected too. Updated the post to try and make some more sense.

  • Robert Nyman says:

    Trygve Lie,

    Nice, thanks for the tip!

  • […] CSS files downloaded twice in Internet Explorer with protocol relative URLs […]

  • […] CSS files downloaded twice in Internet Explorer with protocol relative URLs […]

  • […] CSS files downloaded twice in Internet Explorer with protocol relative URLs – Robert's ta… (tags: css wordpress ie) […]

  • […] Donโ€™t use protocol relative paths to CSS files […]

  • Mange says:

    This is interesting. I’ve been fighting with getting a css sheet to show up in IE, when it works perfectly fine in FF. As I was looking for solutions to the problem, I found this article.
    As a side note, it turns out I had the stylesheet’s “href” attribute last, which threw IE6 off (yes, my job still uses IE6 for accessing internal sites). On the plus side, 2 hours of frustration at this caused me to find several really well-written blogs such as this one.

  • Robert Nyman says:

    Mange,

    Interesting about the order. And good luck!

  • […] IE ? css ???????? (? IE9 ???)??CSS files downloaded twice in Internet Explorer with protocol relative URLs??script ?? relative path ?????? css ?…??????? js […]

Leave a Reply to Anders Ytterstr&ouml Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.