5a Missing schema double download
This is the first of five quick posts about some browser quirks that have come up in the last few weeks.
Internet Explorer 7 & 8 will download stylesheets twice if the http(s) protocol is missing.
If you have an HTTPS page that loads resources with “http://” in the URL, IE halts the download and displays an error dialog. This is called mixed content and should be avoided. How should developers code their URLs to avoid this problem? You could do it on the backend in your HTML template language. But a practice that is getting wider adoption is protocol relative URLs.
A protocol relative URL doesn’t contain a protocol. For example,
https://stevesouders.com/images/book-84x110.jpg
becomes
//stevesouders.com/images/book-84x110.jpg
Browsers substitute the protocol of the page itself for the resource’s missing protocol. Problem solved! In fact, today’s HttpWatch Blog posted about this: Using Protocol Relative URLs to Switch between HTTP and HTTPS.
However, if you try this in Internet Explorer 7 and 8 you’ll see that stylesheets specified with a protocol relative URL are downloaded twice. Hard to believe, but true. My officemate, Steve Lamm, discovered this when looking at the new Nexus One Phone page. That page fetches a stylesheet like this:
<link type="text/css" rel="stylesheet" href="//www.google.com/phone/static/2496921881-SiteCss.css">
Notice there’s no protocol. If you load this page in Internet Explorer 7 and 8 the waterfall chart (nicely generated by HttpWatch) looks like this:
Notice 2496921881-SiteCss.css
is downloaded twice, and each time it’s a 200 response, so it’s not being read from cache.
It turns out this only happens with stylesheets. The Missing schema, double download test page I created contains a stylesheet, an image, and a script that all have protocol relative URLs pointing to 1.cuzillion.com
. The stylesheet is downloaded twice, but the image and script are only downloaded once. I added another stylesheet from 2.cuzillion.com
that has a full URL (i.e., it starts with “http:”). This stylesheet is only downloaded once.
Developers should avoid using protocol relative URLs for stylesheets if they want their pages to be as fast as possible in Internet Explorer 7 & 8.
The five posts in this series are:
Morgan Cheng | 10-Feb-10 at 6:19 pm | Permalink |
Thanks for sharing this knowledge.
According to your experimentation page, IE7/IE8 treat stylesheet resource this way by checking its type instead of resource extension. Seems there is no workaround for that.
Rob L. | 10-Feb-10 at 7:43 pm | Permalink |
Can you clarify a bit? Is there any difference between “protocol relative” as described above and shown here with two slashes and the full domain name…
href=”//mysite.com/css/style.css”
… vs. what I usually see (and use) on sites, and is (in my experience) called “root-relative,” with a single slash and no domain name?
href=”/css/style.css”
I have always assumed that the second approach would also use whatever protocol the page had been served with… does it?
T.J. Schuck | 10-Feb-10 at 8:52 pm | Permalink |
“Root relative” won’t work if you’re referring to a different domain/subdomain.
T.J. Schuck | 10-Feb-10 at 8:53 pm | Permalink |
(Please note that last post was in reply to Rob L. above.)
Jason Grigsby | 11-Feb-10 at 5:19 pm | Permalink |
@tjschuck I think @robl’s questions are good questions.
Question 1: “I have always assumed that the second approach would also use whatever protocol the page had been served with… does it?”
Yes, that is correct. As @tjschuck points out, root relative will only work if the resource being referenced is on the same domain as the html document itself.
Question 2: This is actually an implied question. Do IE7 and IE8 download stylesheets twice if you use root relative urls or does it only happen if you’re using protocol relative urls?
Steve? Do you know. Have you tested that?
Steve Souders | 11-Feb-10 at 8:53 pm | Permalink |
Hi, Jason!
@tjschuck: Double download does not happen with root relative URLs. Only protocol relative URLs.
Billy Hoffman | 13-Feb-10 at 11:37 am | Permalink |
Steve,
Turns external CSS files referenced using protocol relative hyperlinks in @imports also results in a double download. Not that you should be using @import anyway, but both and @import result in double downloads.
Billy Hoffman | 13-Feb-10 at 11:39 am | Permalink |
ack! silly HTML filtering! Long story short, both using either [LINK] or @import to reference an external style sheet using a protocol relative URL results in IE7 and IE8 double downloading the file.
Matthew Pennell | 19-Feb-10 at 8:05 am | Permalink |
Steve,
I would have assumed that the reason the protocol-less stylesheet on your test page is a 200 (non-cached) resource is that you have a querystring timestamp added to it.
If you remove those timestamps, are the resources cached? Specifically, is the second of the downloads of the protocol-less stylesheet loaded from cache.
Miller | 28-Feb-10 at 4:08 pm | Permalink |
Hi, I test many times on IE7 on Vista and use HTTPWatch ã€Fiddler to capture, but can’t reproduce this problem, is it the same when capture with Fiddler? and could you tell what’s the version of your httpwatch?
Steve Souders | 28-Feb-10 at 6:02 pm | Permalink |
@Matthew: If the cache is empty, the stylesheet is fetched twice regardless of expiration headers.
@Miller: Perhaps Fiddler is affecting your tests. Fiddler (and other proxies) affect browser behavior. I’m using the latest HttpWatch.
Klaus Johannes Rusch | 03-Mar-10 at 11:54 pm | Permalink |
I have been unable to reproduce this behaviour using Internet Explorer 7.
Watching traffic with Fiddler shows no duplicate entries.
Requesting test pages using a direct connection without an intermediate proxy shows no duplicate entries in the logs either.
Maybe this affects certain versions of Internet Explorer only?
Jon Galloway | 02-Sep-10 at 12:45 pm | Permalink |
This appears to be a problem with the latest IE9 preview.
http://www.flickr.com/photos/jongalloway/4951687517/
Eric Lawrence [MSFT] | 02-Sep-10 at 3:14 pm | Permalink |
The reason that the problem appears intermittently isn’t related to Fiddler, but instead to timing.
Internal to Trident, the download queue has “de-duplication” logic to help ensure that we don’t download a single resource multiple times in parallel.
Until recently, that logic had a bug for certain resources (like CSS) wherein the schema-less URI would not be matched to the schema-specified URI and hence you’d end up with two parallel requests.
Once the resource is cached locally, the bug no longer repros because both requests just pull the cached local file.
Petr Morávek | 20-Dec-10 at 4:11 pm | Permalink |
There is something really weird in how IE7 and IE8 (I have no idea what’s the status of IE9) handles protocol relative URLs. A while ago I stumbled on another bug related to them – page is reloaded after clicking on anchor link instead of simply jumping to the anchor – see the test page, if you’re interested:
http://php5.skauti-pardubice.cz/IE7-missing-scheme-bug.php