Does your CDN do that? /Blog of the DomClick company /Habr
Image taken from the site www.aerotime.aero
Hello everyone, my name is Semyon, I lead the development of partner services at DomKlik. Recently, while working on optimizing page loading, I came across an interesting post from Cloudflare on stream prioritization when working with CDN. I got interested and decided to check if our CDN supports this option of the HTTP /2 standard? For those who are interested in learning more, please see below the cat where we will look at the mechanism for prioritizing HTTP /2 streams and test the operation of some CDNs.
HTTP /2 , let's remember what new this protocol offered us:
HTTP /2 is binary, not text.
Multiplexed streams (the ability to send frames from multiple streams in parallel using a single TCP connection).
Compression of headers.
Application-Layer Protocol Negotiation (ALPN) extension for fast TLS operation.
There is no longer the need to shard domains with static (the practice of creating multiple domains, for example, static[1-3], Designed to bypass browser restrictions on the number of parallel connections to one host).
Among others, HTTP /2 allows you to prioritize streams when multiplexed.
How Stream Prioritization Works in HTTP /2
Each stream when multiplexed:
you can assign a weight - an integer value from 1 to 256;
you can assign a number to the stream on which it depends.
The combination of weights and thread dependencies allows the client (browser) to build a “prioritization tree” to describe the order in which responses are received. In turn, the server can use this information to allocate resources to priority responses.
It is important to note that the use of stream prioritization mechanisms by the client does not guarantee a specific order of processing and forwarding by the server.
The "parent" threads (on which other threads depend) receive resources first. If two “children” have the same parent, the children receive resources in proportion to the value
weight in the HTTP /2 Stream header.
For example, there are two threads that run within the same TCP connection:
HTTP /2 Stream: 5? weight 1? depends on 5? EXCLUSIVE
HTTP /2 Stream: 6? weight ? depends on 5? EXCLUSIVE
Both streams depend on stream # 5? so it must be the first to receive server resources (CPU, memory, output buffers) for execution. Further, the resources should be distributed between streams 57 and 63 according to the weights: 57 should receive 15/2? and 63 should receive 5/2? i.e. thread 57 should receive three times as many resources.
Why is it important at all?
With HTTP /? the client opens one connection to the server. All static is loaded over this connection: CSS, JS, images, fonts, etc. In what order should I download them? Or maybe all together in parallel?
It is bad to download all artifacts at the same time, as it increases the overall page load time and often does not make sense for the user on the first screen. Let's say we have a page that displays thirty images, but on the first screen, the user only sees five of them. In this case, it is better to load the first five images and the rest after the user sees the first screen. Or, for example, there are JS scripts that are loaded with async or defer - they can also be left for later. Those. first, you need to use the full width of the channel to download artifacts that will help the user see the first screen (CSS, JS, fonts), and only then download less important things.
What about CDNs?
Browsers can use a thread prioritization mechanism to tell the server their preferred order of fetching resources. However, it turns out that not all servers use this mechanism for resource allocation.
The test is performed using a dedicated resource at https://www.webpagetest.org
It is necessary to set the parameters of the experiment:
- Select a picture about 100 Kb in size on the checked resource;
- Web Site URL: specify https://www.webpagetest.org/http2priorities.html with parameter
imagefrom the previous step.
Browser choose Chrome.
Location is not that important, but it is logical to choose closer to the edge location of your CDN.
It is better to specify a slower Connection, "3G Fast" (1.6 Mbps /768 Kbps, 150 ms RTT).
Runs to indicate more, up to nine.
The CDN test was written by a Chrome developer, so it implements the prioritization logic used in that browser.
Once launched, the test will perform the following steps:
Will download HTML document (request # 1).
Will load the picture specified in the test twice (requests # 2 and # 3).
Establishes and "warms up" the TCP connection with the server.
Will add a unique hash to each of the requests to make sure the images are delivered over the network and not from the cache.
Will request an image from the server 30 times with low priority (requests # 4-33).
Wait for the two low-priority images to load to allow the server to fill the buffers with data.
It will request an image with high priority and wait for a full download (request # 34).
Will request high priority image (request # 35).
The CDN we (external contractor) are using
As you can see from the graph, our CDN paid attention to the priority of streams, reallocated resources and loaded images with high priority in a comparable time with the reference time, much earlier than low priority.
I decided to compare the test results with some well-known CDN and took Cloudflare from AWS for this. The result surprised me:
As it turned out, Cloudflare does not take into account thread priorities: the execution time of the first priority request was an order of magnitude higher than the reference one, and the second priority request ended completely later than many low-priority ones.
We looked at the HTTP /2 thread prioritization mechanism and tested the work of some CDNs. It turned out that not all CDNs, even the largest and most famous, support this option of the HTTP /2 standard.
HTTP /2 standard RFC7540
O'Reilly book High Performance Browser Networking
Repository with CDN test by Patrick Meenan
Clouldflare's article on Stream prioritization
It may be interesting
Not every one of those horrendous areas and furthermore great obliging.