Jeremy Wagner's

Web Development Blog

With occasional rambling diatribes about other stuff.

Stop Using the Protocol-relative URL

July 22, 2016

Paul Irish wrote about the protocol-relative URL way back in 2010. It was a convenient little post that advised developers to abandon absolute protocol URL schemes using http:// or https:// in favor of a protocol-relative variant that looks something like this:


<script src="//code.jquery.com/jquery-2.2.3.min.js"></script>

This convenient syntax eliminates the need for developers to construct URLs based on the user's current security context. If this syntax was used on an HTTP page to include something from a CDN, it retrieved the HTTP version. If the user used it on an HTTPS page, it retrieved the HTTPS version. Seems like a hell of an idea, right?

What could possibly go wrong?
What could possibly go wrong?

When Paul Irish wrote about this in 2010, it was a great piece of advice. We were living in a time when the web only adopted HTTPS when product owners and developers deemed it necessary, such as when viewing or entering sensitive information. The web is different now, though. We are rapidly moving toward a "secure by default" mindset, even for content that may not be considered sensitive. This is a good thing.

Paul Irish has since changed his stance, and now advises against using this URL scheme to reference cross-origin resources. His rationale is that while using the scheme on HTTPS pages is safe, the reverse is not true. Using the scheme on an HTTP page will retrieve cross-origin assets in an insecure fashion. This is not good, and it's rather easy to just slap an https:// protocol on your URLs to ensure that your site is requesting encrypted assets.

The problem isn't only with security. This URL scheme has the potential to also impact performance. Many of the new and shiny features that are starting to come into prominence will only work if SSL is enabled, and if you're using CDN-hosted resources over HTTP, you're missing out.

HTTP/2

The biggest thing you're missing out on if you use the protocol-relative URL over HTTP to reference CDN assets is HTTP/2. Without parroting too much of what so many bloggers have already said out there, HTTP/2 solves a number of performance problems for us. The big one is that it solves the head of line blocking problem present in HTTP/1. In HTTP/1, requests are batched together and executed six at a time. The next batch of six requests, however, can't begin to download until all of the requests in the previous batch have been fulfilled.

If you have a website that grabs a lot of resources from a single CDN over an insecure connection, you could actually be forcing an HTTP downgrade if that server supports HTTP/2. Below, you can see a request for jquery.min.js on Cloudflare's CDN on both HTTP and HTTPS:

Note the values of the protocol and scheme columns.
Note the values of the protocol and scheme columns.

You can see that when the resource is requested over HTTPS, the value of the protocol column is "h2", which signifies that the resource is being transmitted using HTTP/2. However, when the same resource is requested on the same domain over an insecure HTTP connection, the connection downgrades to HTTP/1.1.

Head of line blocking isn't the only reason to embrace HTTP/2. This new protocol compresses headers that are transmitted with requests and responses, something that HTTP/1 has failed to address. If you want to shave a few more bytes off of those requests, then slap that https:// on your CDN references.

Side note: HTTP/2 isn't the only protocol you might be missing out on, either. Google Fonts uses the QUIC protocol, which uses UDP rather than TCP. Like HTTP/2, this protocol requires an HTTPS connection.

Brotli

Google's been hard at work on Brotli, its contender to the venerable gzip. Brotli support now ships with Chrome as of version 50, and Firefox has supported it since version 44. Other Chromium-based browsers such as Opera 38+ are throwing in support for it, as well.

Google has sung the praises of Brotli, and has even used it to compress WOFF2 font files in a standalone fashion, yielding another 30% savings over its WOFF predecessor. When used on web servers, it can be a mixed blessing. I'm currently using a build of mod_brotli for this site, and it yields a modest performance gain of only around 3-5% at the default settings when compared to gzip running under its default settings.

In my book Web Performance in Action, I noted that the gains are relatively modest unless you're using very high compression settings. The problem with this, though, is that the compression takes so long that it actually performs worse than gzip. There are some ways around this, particularly if you cache the compressed result on disk, and serve that content on subsequent requests. This approach is called static compression. With it, we can realize some serious performance gains using Brotli without suffering from its current performance problems at high compression settings.

The thing about Brotli is that, like HTTP/2, you must be using HTTPS in order to benefit from it. Currently, Google Fonts serves CSS using Brotli (and HTTP/2!) over HTTPS, and gzip over HTTP. This may not sound like a big deal, but there are two things to remember about Brotli:

  1. Not all CDNs have fully adopted Brotli, but they likely will at some point. When they eventually do, they have tremendous resources to statically compress content, and serve it to the client without performance penalties.
  2. Brotli is a nascent technology compared to gzip, which has been around for quite a long time. As Brotli changes, its performance could change.

In short, if you persist in using the protocol-relative URL from an insecure origin, you might be cheating yourself of a new compression technology when referencing CDN assets. If you can squeeze a little more performance out of a page with little effort, wouldn't you want to?

Isn't HTTPS Slow?

The short answer? No.

The (somewhat) longer answer: On HTTP/1.1? Potentially, since more than one connection is opened per origin, and the overhead of setting up a secure connection occurs more often. On HTTP/2, there is only one connection per origin, so this process only occurs once. Furthermore, modern hardware renders the impact of HTTPS overhead to be far less significant than it may have been mere years ago. If you want to know more, visit IsTLSFastYet.com.

The last thing you should be worried about with your references to CDN assets is HTTPS performance. If anything can mitigate whatever performance issues exist, it's the deep pockets of companies like Google that can invest in more resources to lessen the impact. Furthermore, if your CDN is running HTTP/2, HTTPS performance is a non-issue when you consider the performance benefits that it provides.

Conclusion

If you've been referencing cross-origin resources with the protocol-relative URL scheme, it's time to stop. Especially if you're doing so from an insecure origin. You're likely missing out on the performance benefits of HTTP/2, and maybe missing out on Brotli compressed content. There may even be more performance benefits that you're missing out on that I haven't listed here. If you know of any, pipe up in the comments!

Hopefully this little post has proved useful to you. We all have a part in making the web faster for everyone, which is usually no small task. Except for the advice prescribed in this post. It's a small task. If we all embark on it, it can inch us a little bit closer to a faster and more secure web for everybody. It's incremental change we can all get behind.

Cheers,
-j

Thoughts? Let's hear them!