Why You Should Not Use Protocol‑Relative URLs

In Brief
Use an explicit https:// URL for an external resource, or an ordinary relative URL when the resource shares the page's origin. A protocol‑relative // URL inherits the page's scheme, which means an HTTP page can still request it insecurely and the transport requirement is no longer explicit. The pattern solved a historical migration problem that modern HTTPS sites should not recreate.
When you link to another website or load an external resource, you will generally specify the protocol that the browser should use within the URL. For example, if you wanted to load React via the official CDN links, it would look something like this:
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script><script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>The use of https:// at the beginning or src will force the visiting browser to load these resources with HTTPS. You could equally switch those out for simply http:// to load over HTTP instead (if the source allows).
On an HTTPS page, modern browsers block or upgrade many HTTP subresources rather than merely warning after execution. An HTTP page remains vulnerable to on‑path modification, and a protocol‑relative resource on that page inherits HTTP.
Traditionally, the answer to this has been to use protocol‑less (or Protocol‑relative) URLs. These remove the protocol altogether (simply starting with a double slash: //), and allow the hosting page to determine which protocol is used. If the page itself is HTTP, then HTTP will be used, and vice versa.
Using the original React example:
<script src="//unpkg.com/react@17/umd/react.production.min.js"></script><script src="//unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>I touched upon it earlier, but just to be clear: don't do this for external resources. On an HTTPS page the URL inherits HTTPS, so the double‑slash form is not an extra risk there. The problem is that it also inherits HTTP on an insecure page and hides the intended scheme from the source.
Whilst obviously dropping those 'http' characters saves on a few bytes of data (although ‑ honestly ‑ are you really that strapped for space?), and removes a bit of decision‑making from the development side, it also comes with some very severe downsides too.
For external resources, specify HTTPS explicitly rather than hiding the scheme. Same‑origin links do not need an absolute scheme. HTTPS encrypts data in transit, provides integrity, and helps authenticate the endpoint; it does not by itself secure the server, its files, or the wider business systems.
HTTP/2 is commonly deployed over TLS and can improve some workloads, but performance depends on the connection, server, content, and protocol negotiation. Security is the reason to require HTTPS, not a blanket speed guarantee.
A protocol‑relative URL does not let the browser choose arbitrarily; it inherits the document's scheme. On an HTTP page that means an insecure request vulnerable to on‑path interference, which should be unnecessary when building a website or app in 2022. The 2015 interference with GitHub is one example.
The bottom line is that external resource calls should specify HTTPS. For same‑origin page links, ordinary relative URLs such as /about/ are correct and inherit the secure origin.