SRI, or Sub-Resource Integrity, is a new-ish technology that I’m a big fan of. It’s something that’s so easy to implement, especially if you’re using a workflow tool such as Gulp, but also so powerful when referencing third party or CDN-hosted libraries, to avoid inadvertent or breaking changes.
A few days ago I posted about adding Sub-Resource Integrity (SRI) checksums with Gulp which shows just how easy it is to implement this. However, I found a bit of a “gotcha” with it the other day. I spent a while scratching my head, and even posted on StackOverflow, although I ended up answering my own question.
When using HTTP/2 server push, which I’ll cover in more detail in a future post, you cannot use SRI.
HTTP/2 is pretty clever, for example allowing one TCP connection to be utilised by multiple concurrent downloads, which means there’s less delay waiting for both TCP connections to be setup and also for files to be downloaded. Another is that the server can push files down the connection, before the browser asks for them. So if you fetch a web page, the server can return the web page but also the stylesheet, so that when the browser requests the stylesheet, it can get it from the cache, even though the user has never been there before, because the server has already pushed the file.
However, if you push a file into the cache using server push, but then your reference to the file has SRI attributes, the browser will fail the validation, even though the file is correct, and download the file again. This looks something like this…
You’ll also get a message in the developer tools console saying…
A preload for ‘https://whysoslow.co.uk/lib/bootstrap.min.css’ is found, but is not used due to an integrity mismatch.
This appears to simply be because this hasn’t been implemented by browsers yet, which is a shame. Hopefully that changes in the future. However, in this instance I was hosting the file locally myself, so it wasn’t such a big deal and I opted to remove the SRI attributes to get the performance benefit of server push.