One of the first things that I recommend to my customers to speed up websites is, at first, a paradox: you have to put static resources on your hosting, abandoning third-party CDN infrastructure. In this short and, I hope, very simple post, I want to outline the disadvantages of storing your static files “on the side” and the tremendous advantages of hosting them on your hosting.
What I'm talking about?
It’s common for developers to link to static assets, such as libraries or plug-ins, that are located on sites and CDN resources. The classic example is jQuery.
There are a number of obvious advantages here, but my goal later in the article is to expose this approach, and to show that the disadvantages dominate significantly.
(First consider the advantages).
')
- It's comfortable. This requires very little effort to attach files. Copy a line of HTML code, and you're done. Easy.
- We get access to CDN. code.jquery.com is supplied by the StackPath, this is a CDN. By connecting to the content on this resource, we get the delivery of CDN-quality, for free.
- User files may already be cached. If website-a.com refers to code.jquery.com/jquery-3.3.1.slim.min.js , and the user goes from here to website-b.com, which also refers to code.jquery.com/jquery-3.3 .1.slim.min.js , then the user will have this file in the cache.
Risk: Falling Speed ​​and Crashes
I will not go into too many details in this post. I have a whole article about the viability of third parties and the risks associated with delays and interruptions. Suffice it to say that if you have any critical resources related to third-party providers, and if the provider suffers from crashes and drops in speed or outages, this is pretty bad news for you. You too will suffer from this.
If you have any render-blocking CSS or synchronous JS hosted on third-party resources, go and transfer them to your own infrastructure immediately. Critical assets are too valuable to leave on third-party servers.
Risk: Termination of Service
This is much less common, but what happens if the provider decides that it needs to stop servicing? This is exactly what Rawgit did in October 2018, so far (at the time of writing), a rough search of the GitHub code still gives more than a million links to the service, which is currently in the process of being closed, and almost 20,000 active sites continue refer to it.
Risk: Security Vulnerabilities
Another thing to look out for is a simple matter of trust. If we bring content from third-party resources to our page, we have to hope that the files we receive are exactly what we expect to receive, and they do exactly what we expect from them.
Imagine the harm that could have been caused if someone managed to gain control of a provider, such as code.jquery.com, and start delivering compromised or malicious content. It's scary to think about it!
Subresource Integrity
We must pay tribute to all third-party providers mentioned so far in this article, they are doing everything to ensure the integrity of sub-resources (Subresource Integrity - SRI). SRI is the mechanism by which the provider provides a hash (technically, a hash followed by Base64 encoding) of a specific file that you expect and intend to use. The browser can then verify that the file you received is exactly what you requested.
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=" crossorigin="anonymous"></script>
Again, if you definitely need to connect static content to a third-party resource, make sure that SRI is in effect. You can connect SRI by yourself.
Payback: Network Negotiations
One of the biggest and most urgent costs we incur is the cost of opening new TCP connections. Each new resource that we need to visit requires opening a connection, which can be very costly: DNS resolution, TCP handshake, TLS negotiation, all this contributes to it, and the story gets worse as the connection delays.
I'll give an example taken directly from Boostrap's Getting Started page. They instruct users to connect four files.
These four files are on three different resources, that is, we need to open three TCP connections. How much is it? Well, with a fairly fast connection, the content of these static files on the side is 311ms, or 1.65x slower than when they are placed on their own hosting.
By contacting three different sources for serving static assets, we collectively lose the unnecessary 805ms for network matching.
OK, it's not so scary, but Trainline, my client, found that while reducing the delay by 300ms, visitors pay an additional 8 million pounds a year. This is a fairly easy way to earn 8 million.
Only by moving our resources to your domain, we completely eliminate the cost of additional connections.
For a slower connection, with a longer delay, the story is much worse. For 3G, the third-party version comes slower than 1.765s. I figured that I meant to make our site faster.
When connected with a large delay, the total network costs amount to a monstrous 5.037s. What can be completely avoided.
Moving files to our own infrastructure reduces download times from 5.4s to 3.6s.
If this is not enough reason to place your static resources in your own home, I don’t know what else to bring.
Preconnect
Naturally, the whole point of my speech here is that you should not place any static resources on the side, if you are able to do it on your hosting. However, if your hands are somehow connected, you can use Resource Hint preconnect to proactively open a TCP connection from a specific source (specific sources): Moreover, deploying them as HTTP headers will be even faster.
Note. Even if you use preconnect, the amount of time lost will decrease only slightly: you still need to open the appropriate connections, and it is unlikely that costs will ever be justified, especially for slow connections.
Payback: Loss of Prioritization
The second payment comes in the form of optimization at the protocol level, which we miss at the moment when we divide content by domains. If you use HTTP / 2, what should you do, you get access to prioritization.
All threads (and therefore resources) with the same TCP connection retain priority, and the browser with the server works in tandem to build a dependency tree of all these prioritized threads so that we can return critical resources faster and possibly delay the delivery of less important ones.
Note. Technically, due to the splicing of HTTP / 2 connections, requests can be prioritized against each other across different domains as long as they share the same IP address.
If we distribute our resources across different domains, we have to open several unique TCP connections. We cannot make cross-references for priorities in these connections, that is, we lose the ability to deliver files in a certain well thought-out way.
By placing all the content on one hosting, we can build a more complex dependency tree. Each thread has its own ID, as they belong to the same tree. If we provide as much content as possible from one domain, we can allow HTTP / 2 to do its job and prioritize assets more fully in the hope of a faster response.
Caching
By and large, static resource hosts seem to do a good job of setting long-lived max-age directives. This makes sense since static content on versioned URLs (as mentioned above) will never change. This makes it very safe and rational to enforce a reasonably aggressive caching policy.
However, this is not always the case, and by independently allocating your resources, you can develop much more individual caching strategies.
Myth: Cross-Domain Caching
More interesting is the ability to cross-domain asset caching. That is, if many sites refer to the same version of jQuery hosted on a CDN, then users probably already have this particular file on their computer. Something like peer-to-peer resource sharing. This is one of the most common arguments for using a third-party static asset provider.
Unfortunately, there is no published evidence supporting these statements: there is no reason to assume that this is true. Conversely, a recent study by Paul Calvano hints that the opposite may be the case:
There is a sizeable gap between the age of the CSS resource cache and the 1st and 3rd web fonts. 95% of 1st party fonts are older than 1 week compared to 50% of third-party fonts that are less than 1 week old. This gives a good reason for self-hosting web fonts.
In general, it seems that third-party content is cached worse than its own.
More importantly, Safari has completely disabled this feature due to concerns about privacy abuses, so shared cache technology cannot work at the time of this writing for 16% of users worldwide.
In short, although theoretically it is good, there is no evidence that cross-domain caching is somehow effective.
CDN access
Another widespread advantage of accessing a static resource provider is that it will most likely use a powerful infrastructure with CDN capabilities: global distribution, scalability, low latency, and high availability.
Since this is absolutely true if you care about your performance, you should run your own content from the CDN. With the level of current prices for hosting there are very few excuses why you do not use it for your resources.
In other words: if you think you need a CDN for your jQuery, you will need a CDN for everything.
Host static resources on your hosting
In fact, there are very few reasons to leave your static resources in a foreign infrastructure. The possible benefits are often a myth, and even if not, the compromises are simply not worth it. Loading resources from different sources is much slower. Over the next few days, spend ten minutes auditing your projects and taking all third-party static resources under your control.