Content-Delivery Networks
Learning Objectives
- You know what content-delivery networks are and how they can be used to improve web application performance.
- You know of Jamstack and how CDNs can be used with contemporary web applications.
Content-delivery networks
Content-delivery networks (CDNs) are networks of servers primarily used for distributing static content. The use of CDNs can lead to significantly fewer requests to the application servers as the requests for static resources can be handled by a CDN.
As CDNs are distributed and often have servers in multiple locations, they can also lead to faster web application load times as the static resources can be loaded from servers that are close to the user. In addition, CDNs can increase the reliability of the application, as resources on CDNs could be available even if the application servers would not be available.
In practice, when a CDN is used, the static content of a web application provides links to resources that are on CDN servers, and the browser then retrieves those resources from the CDN. An example of a possible HTTP response is outlined below.
HTTP/1.1 200 OK
(headers)
<html>
<head>
<link
rel="stylesheet"
href="https://s1.cdn-srvr.com/identifier/styles.css">
</head>
<body>
<img
src="https://s2.cdn-srvr.com/identifier/retro-sax-guy.gif" />
</body>
</html>
When the browser receives a response like the above (regardless of the host of the server serving the response) the browser retrieves the resources at addresses https://s1.cdn-srvr.com/identifier/styles.css
and https://s2.cdn-srvr.com/identifier/retro-sax-guy.gif
. As the host names for the two resources differ (s1.cdn-srvr.com
and s2.cdn-srvr.com
), the browser could simultaneously open a connection to both of them, even if the browser would have a very restrictive one connection per host policy.
Older HTTP specifications, such as RFC2616, limited the number of persistent connections that a browser could have open to a single host. This limitation was relaxed in later specifications. Newer protocols such as HTTP/2 also have multiplexing, which allows multiple requests over a single connection.
Content-delivery networks can also be seen as a shared cache, where cacheable data (static website content) is distributed across servers. These servers typically have a range of hostnames, which differ from the host of the web server(s) responsible for serving dynamic content. However, similar to caching in web applications in general, CDNs also suffer from issues such as stale cache.
Read also the article The Akamai network: a platform for high-performance internet applications.
Using a CDN
The use of content-delivery networks depends on purpose and role of the web applications that use them. Applications that rely on static resources such as client-side code, HTML, styles, and images can offload content to CDNs, which increases the performance of the applications. This holds also for media platforms and services such as YouTube and Netflix, which use CDN servers for storing and distributing the content.
See also A look under the hood of the most successful streaming service on the planet.
Content-delivery networks can also provide an additional layer of security on the application, as they can be used to protect websites from denial of service attacks. For further information, check out Cloudflare’s learning resource on DoS and DDoS attacks.
As a concrete example of CDN use, classic styling libraries are often loaded from CDNs. As an example, when using Bootstrap, the following link is added to the page heading:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
Similarly, when using Milligram, the following links were added to the page heading:
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/milligram/1.4.1/milligram.min.css">
When we consider the links, the CDN that we used for Bootstrap is jsDelivr, while for Milligram (and the content it requires), we used Cloudflare and Google Fonts. Although it might not be clear from the URL, Google Fonts also uses a CDN to serve the font definitions.
One of the interesting aspects of jsDelivr is that it can be used as a CDN for third party services. It can be used to, for example, create a CDN for content on GitHub and for unpkg. This, in turn, would allow deploying static content on GitHub, and use the content through jsDelivr. On the other hand, Cloudflare can be used as a proxy, where all traffic are directed through Cloudflare, potentially also hiding the location of the application.
CDNs and contemporary web applications
With contemporary websites that separate the user interface from the backend, the static user interface code can be fully served from a CDN. This idea is also behind the concept of Jamstack, where static content is pushed to a CDN, while the APIs are managed separately.
Figure 1 outlines the core idea of Jamstack, with the user accessing static content from a CDN, while using APIs through separate services.
With hybrid applications, the flow is somewhat similar. The user still accesses the static content from a CDN, while the dynamic content is served from the application servers. In addition, separate APIs can be used for the dynamic content. This is illustrated in Figure 2 below.
Effects of using a CDN
To concretely see the effects of using a CDN, we can compare the loading times of a web application with and without a CDN.
First visit the address https://holy-pine-5084.fly.dev/. The address https://holy-pine-5084.fly.dev/ hosts a simple application that shows an image (the page is intentionally created on the server using server-side rendering, although it could also be a static site). The application works so that on request to the root path of the application, the count used to select the displayed image increases by one, and thus the image changes during page reloads. When we make a request to the site, we receive (for example) the following response:
curl -v https://holy-pine-5084.fly.dev
* Trying 2a09:8280:1::3:91c0:443...
* Connected to holy-pine-5084.fly.dev (2a09:8280:1::3:91c0) port 443 (#0)
...
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
<link rel="stylesheet" href="https://unpkg.com/papercss@1.8.1/dist/paper.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="utf-8">
</head>
<body>
<div class="container paper">
<h1>Current image: 1</h1>
<img src="/static/1.jpg" />
<p>Image author <a href="https://unsplash.com/@alanking">https://unsplash.com/@alanking</a></p>
<p><em>All images from <a href="https://unsplash.com/" target="_blank">Unsplash</a> unless otherwise noted.</em></p>
</div>
</body>
</html>
Whenever the address https://holy-pine-5084.fly.dev/ is visited, the image is also retrieved from https://holy-pine-5084.fly.dev/
. In terms of the loading times (depending on traffic and omitting browser cache), from one location in Finland, the time that the image would take to load is in the range from 100 ms to 170ms, as outlined in Figure 1.
Next, visit the address https://www.scalable.website/. The scalable website uses Cloudflare for caching the static under the path /static
. That is, the address https://www.scalable.website/ has the same application as the previous address — even to the extent that the actual application server is the same (the one at fly.dev) for both, but the image is served from Cloudflare.
When considering the load times for the image from the scalable website, as shown in Figure 2, the loading times are significantly lower. Instead of 100-170ms for the image from the fly.dev server, the loading times are between 60 and 100ms (again, from a single location in Finland).
This means a reduction of 40-70ms in loading times for the image. In addition, the application server would receive fewer requests for the image, as the image would be served from the Cloudflare cache.
Additional information on how to use a Cloudflare Cache / CDN is available on the Get started page of Cloudflare.
Some countries and governments seek to limit access to information. One way to do this is to block CDNs as they can be used for masking information sources.
When taking a CDN into use, workarounds may be needed for some countries. For additional details, see e.g. When Your CDN-Hosted Site Hits The Great Wall of China — a Workaround Story.
CDN providers and serverless
While CDNs initially focused on distributing static content, they have increasingly moved towards the serverless space. This means that CDNs can be used for executing code on the edge, which can be used for e.g. processing requests, handling authentication, and so on.
As an example, Cloudflare Workers can be used to run code on the edge, which can be used for e.g. processing requests, handling authentication, and so on.