Can we pick a CDN already?
Posted
Last updated
People are well aware of the importance of performance. Minifying sources and enabling caching are ubiquitous across the web. However there are still some things that need to be improved, namely avoiding downloading common resources.
Well over half of the top sites on the web use jQuery, yet when visitors visit my site they often have to download it again, even though it is surely in their cache multiple times. There must be a solution to this problem.
I have heard a number of people say something along the following lines. “Web browsers should have a built-in version of popular libraries”. While this is an interesting thought it is a fairly bad idea. First of all there would need to be a new syntax for requesting these files, and a way to fall back if the browser doesn’t have the script you want. Plus the browser vendors would have to manage adding new versions and removing old ones, a bunch of politics they don’t want to get into.
But what if I said that there was a way, where browsers download these scripts on demand, and everyone could use the same copy. This means that the average user should only have to download jQuery once and every site that wanted it could use it.
Feel free to hold your breath, it already exists and it is plain old caching as you’ve known it for years. The problem is that everyone has their own version, and more importantly it is at a different URL.
Much like we have learned from REST, that every object should have a URL. We should also start practicing every object having exactly one URL. Simply put, if everyone used the same URL for jQuery (and other popular libraries) the cost of downloading jQuery would effectively disappear. It would be like having it builtin to the browser, without the administration overhead.
How to help solve this issue
It’s pretty simple, use public CDNs.
Well not that simple. It turns out there are too many public CDNs, reducing the benefit as the requests are divided across them. So what do you do? Ideally the project recommends a CDN. For example jQuery has it’s own CDN and you should use it as the primary source for jQuery.
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
And then you can fall back to others (including a local copy), and I would recommend using the order the project list them in (if they do). For example jQuery has a list as follows.
What if they don’t recommend a CDN copy?
If the project doesn’t have a CDN recommendation I would make a suggestion that they pick one. This way they can update their docs and everyone can start using the canonical copy. If their file isn’t on a CDN then you can try to add it to a public CDN such as jsDelivr or CDNJS or if you have access to a good CDN you might even offer to host it yourself.
Unfortunately hosting files costs money so it may not be possible, but if the project isn’t popular enough to be included by either of the CDNs I listed above the caching benefits are probably negligible anyways. If this is the case just bundle it into your app until the library gains more popularity.
What should I do if I am a library developer.
If you are a library developer you have the biggest role in this. It is your job to clearly recommend a CDN that your users should use. Furthermore I would recommend keeping each release at the same URL forever. Feel free to switch CDNs with new releases but if at all possible keep the old URLs the same because old users are unlikely to update to the new one.
But shouldn’t I bundle my assets?
Kinda, but caching is better. When you bundle your assets you are forcing the browser to download a massive glob of stuff. It is great to bundle the data specific to your site, but for external scripts you should load them off a CDN. Modern browsers support SPDY and HTTP2 is just around the corner. These greatly reduce the cost of requesting multiple files. And test have shown that they are as fast as bundled assets, without breaking granular caching. With modern browsers bundling will actually hurt your performance because every time you update a single file they have to re-download all of your code.
But wont many domains cause a number of DNS requests?
Yes, but if the project is popular enough to have its own CDN (or domain name on the CDN) the likely hood of it being cached is well worth the chance of an extra round trip. And most of the smaller projects will be on a public CDN which will likely already be in the DNS cache, so no need to worry.
But what if the CDN goes down?
This is a valid point. The answer is to fall back. Unfortunately this is slow but it is also rare. If a script fails to load just request it from another CDN, or a version you host yourself. There is also the chance that the browser already has all of the scripts you need cached, and the client won’t even notice the CDN is down.
Are you sure about this?
Yes, technologies have sufficiently increased that we no longer need to serve all of the script bundled and the advantages of caching are so large now that many sites are built using popular frameworks that are often quite large. The only remaining issue is the chicken and egg problem, so lets break out of that now. Let’s get every script a canonical URL and let caching work it’s magic.