In the previous post we discussed how HTTP/2 can help us optimise our web application. We looked at multiplexing, header comprehension and other features of HTTP/2 and how they addresses a lot of shortcomings in HTTP/1.x protocols. In this post we will look at another feature introduced by HTTP/2 called server pushes. Understanding server pushes can help us optimising for performance in our web application.
As the name suggests server pushes are unsolicited push messages from the server to the client. HTTP protocol revolves around concepts of requests and response and there is a one to one relationship between a request and a response. With HTTP/2 the request and response now have one to many relationship i.e. in HTTP/2 a request by client can receive multiple response by the server.
Modern web applications require to load a lot of resources to render one page such as multiple images and other static assets. If you are familiar with practice of in-lining of static assets you are actually familiar with server pushes already. In-lining of resources in HTTP/1.x is a work around that simulates HTTP/2’s server push in order to save an additional HTTP call to the server. Inlining static assets is also a trade off. Inlining a large sized resource may increase the over all page load time even if we succeed in reducing the number round trips. Server pushes in HTTP/2 serves the same purpose of saving additional HTTP calls but it comes with some additional advantages like caching of resource which is pushed and reusing resources across different pages. Pushed resources are streams in HTTP/2 and can be multiplexed and prioritised like other streams. HTTP/2 uses server pushes to preemptively push data to the client as the clients needs. So you no longer need to inline resources in order to optimise the page load time.
Before we look into how the push messages are being sent by the server we will look at some terminology. In the previous post we discussed about three fundamental terms in HTTP/2 that are frames, messages and streams. You can quickly recall them here. In this post we will add one more term to our HTTP/2 dictionary which is
PUSH_PROMISE is a type of frame in HTTP/2 which is used to notify the client in advance that server is about to send a stream to the client. This frame includes the information about the stream which is about to be sent to the client. Read more about it here. A scenario where a client is not notified beforehand about the data which is being pushed by the server and client issues a different request to fetch the same resources may lead to request races. The sole purpose to
PUSH_PROMISE frame is to avoid such conditions.
PUSH_PROMISE frame is sent on the stream which belong to the request that need resources to be pushed. This frame includes the stream identifier of the promised resource which are chosen from available stream identifiers on the server. The server sends this
PUSH_PROMISE frame before sending any frame that reference the promised data to avoid any request races. Sending
PUSH_PROMISE creates a new stream on the server which is later used to push the promised resource. As soon as the
PUSH_PROMISE is being sent server starts so send the promised resources. When client receives the
PUSH_PROMISE frame and it choses to accept the pushed data it does not issue any request to fetch the promised data.