HTTP/2 Server Push Gotchas

Challenges of implementing HTTP/2 server push to gain from it's performance benefits.

Jan 31, 2019



HTTP/2 server push is one of the most lucerative features of the HTTP/2 protocol. The fact that the server need not wait for the browser to request the critical assets it knows browser would eventually request is an obvious win. More so on slower connections where the round trips can be costly. Elimination of a single round trip makes it even more performant than preloading content. And given that the pushed asset would still benefit from browser caching makes it even more performant (and easier to maintain) than inlined code.


However, I have not yet come across a situation where I have leveraged the benefits of HTTP/2 server push. This post lists the gotchas that prevent us from benefiting from HTTP/2 server push.


How HTTP/2 server push works
Client - server communication with HTTP/2 Server Push

In theory, HTTP/2 server push can perform better than preloading or code inlining. But, it hasn't been adopted as widely as expected due to ground reality challenges implementing it.



Handling returning visitors

Returning visitors may already have a cached copy of the files you intend to push. So, it is optimal to not perform HTTP/2 push for returning visits. You can achieve this by making your HTTP/2 push cache aware through cookies. You can easily achieve this through web server configuration (like nginx or apache) or server-side code changes (like PHP or Node JS). But, a cache-aware push mechanism can get complicated very quickly (as we shall read in following sections).

How cache aware HTTP/2 server push works
Cache aware HTTP2 server push


Handling returning visitors and your site's code changes

You would not want to push files that a returning visitor already has in his HTTP cache. But, what if these files are updated since the visitor's last visit? You would definitely want to push a file to a returning visitor that has been updated since his last visit. This can be achieved through cookies containing pushed file's fingerprint (version information or hash based on file's content). This post shows how this can be achieved with PHP using MD5 hashing.


This can be managed in code. But, if you are using web server configuration for your HTTP/2 push mechanism, you will have to update the hash values in your configuration every time the asset being pushed changes. This may be manageable for sites that don't change frequently. But, for complex sites with frequent changes, this can get error-prone.

How HTTP/2 server can be cache and code changes aware
Cache and code update aware HTTP/2 Server Push


Pushing page specific critical assets

Maintaining asset specific cookie is manageable if you are trying to push a couple of site-wide critical assets. But, if you have a dozen different critical assets that are needed only on certain parts of your website, you can end up with a large matrix of URL patterns, file-names and cookie fingerprints to manage. This can be cumbersome to manage. More so, if you are using web server config to setup your HTTP/2 push mechanism (like explained in the previous section).

Pushing page or section specific assets can get cumbersome
Web server may push wrong assets if not configured correctly.


HTTP/2 server push and browser inconsistencies

Leaving all the cache awareness complexities aside, there's also browser behavior inconsistency to deal with. Jake Archibald's excellent post details the nitty gritty of this. But, to summarize his points, there can be certain situations where the browser receives the pushed asset but doesn't use it leading to re-download of the same asset. HTTP/2 server push would be detremental to visitors' speed experience in such situations. Jake observed this to happen sometimes on Safari and under certain corner case situations with other browsers.


Conclusion

HTTP/2 server push is aimed at offering the combined benefits of code inlining and caching. But, the job of keeping HTTP/2 server cache aware can quickly get very complicated (esp on websites with many pages / styles / sections). That, along with browser inconsistencies, makes HTTP/2 server push non-trivial to implement and benefit from.


HTTP working group is working on Cache Digests for HTTP/2 (currently in draft) to simplify HTTP/2 server cache awareness. And browsers inconsistencies shall hopefully resolve in future versions. But, until these things happen, one shouldn't set it up without careful planning prior to implementing and judicious testing during implementation.




Punit Sethi

About the Author

Punit Sethi has been working with large e-Commerce & B2C websites on improving their site speed, scalability and frontend architecture. He tweets on these topics here.