Chromium developers have announced that they plan to remove support for HTTP/2 server push from the market-leading browser engine. Server push lets web servers preemptively send clients resources it expects them to request later. The technique can reduce the number of network round-trips required before the client has all the resources it needs to display a page. The announcement cited high implementation complexity, low adoption among websites, and questionable performance gains as the reason for the removal.
Server push is an optional feature introduced in the HTTP/2 standard. Chrome can remove it and remain compatible with the HTTP/2 standard. When used correctly, server push can greatly improve page-load times. It also enables use-cases like instant redirects.
Here’s an example session to highlight what could be done with server push. Let’s say the client connects to a server and requests /document. Without server push, the server responds with a redirect to /document.html. The client receives the response and sends another request for /document.html. The server sends back the requested resources. The client parses the response and discovers that it also needs /page-layout.css and /logo.png to display the page. It sends two more requests for the missing resources to the server, which promptly sends them in return. The client can then finally display the page.
That’s a lot of back and forth between the client and the server. With server-push, the web server can take the initiative without waiting for the client. It can send the redirect, the final document, and the two required resources in response to the initial request.
Web servers don’t give you these performance benefits for free. The server or application must be configured to push the right resources at the right time. When push was first added to web browsers, there was much discussion about servers applying machine learning to automatically learn what resources it should push. Some content-delivery networks, like Akamai, has this capability. However, it has yet to be added to any of the leading web servers. However, I was able to find one open-source implementation of an auto-pushing learning filter for javax.servlet.
The Chrome team has measured the adoption of HTTP/2 push, and found that only 0,05 % of all HTTP/2 sessions seen by Chrome users use server push. The low number suggests that website owners either aren’t aware of the capabilities or benefits of push, don’t have compatible servers, can’t or won’t configure it, or don’t believe it offers performance improvements good enough to justify the investment. At any rate, Chrome doesn’t think such a low adoption rate justifies maintaining its server-push implementation.
I’ve used server push for the last four years here on Ctrl blog to deliver stylesheets when you request an HTML document. The blog uses modular stylesheets tailored to each page to avoid loading and parsing unneeded styles. The median stylesheets for Ctrl blog are relatively small at 4,4 KB compared to the web-wide median of ~70 KB (according to the HTTP Archive). However, I’ve thrown away the potential savings by pushing the stylesheet on every page-load.
Servers aren’t aware of the state of the client’s cache. They can’t know what resources the client has stored from previous visits, and risk pushing assets needlessly. This can waste people’s precious data quotas, slow-down page-loading performance, and cost you more money. A standards proposal called Cache Digests was intended to address this problem. However, no browsers have implemented it since it was introduced in 2016. The proposal has many unresolved issues, such as how to prevent the technology from being used as a “super-cookie”/persistent identifier that can be used o track returning visitors.
I use Apache and have configured it to only push the stylesheets needed for any given page. The blog consists of statically generated files; making it difficult to send dynamically generated HTTP response headers. Who knew Apache could read file contents into a variable and use regex to look for stylesheet? The complexity of this approach is suboptimal, and it hurt the server’s response times too. Luckily, this only needed to be done once per document thanks to mod_cache. I’ve not discussed this method on the blog before, because it’s not a technical debt I’d recommend anyone take on.
The stylesheet-pushing, combined with deferred script-loading, has ensured that pages have been rendered as quickly as possible. After the deprecation of server push, the only open-web way to get similar results is to include the stylesheet inline/embedded in the HTML documents (“inlining.”) Inlined resources don’t benefit from the shared cache, though, so you end up wasting bandwidth the same way you do with needless server pushed resources.
Following Chrome’s announcement, I decided to remove server push from Ctrl blog. It’s still supported in all the leading web browsers, but it’s effectively dead once Chrome pulls the plug. One week after removing it from the site, the performance impact is clear: the median time to first contentful paint (FCP) has increased by 10 % (adding roughly 100 milliseconds). Ouch.
You can still rely on server push, but you should start looking into alternatives. For now, that means you need to revert back to HTTP/1 best-practices like inlining critical page resources. Server push will continue to work in Chrome for some months to come. There haven’t been any public signals from Firefox or Safari about whether they intend to support server push after Chrome has removed it.