> It will take a round trip for the client to tell the server if an object is cached.
Why wouldn't the client be able to give the server some information about what it has cached already when it makes the initial GET request for the HTML page?
"It is not possible" is an overly strong claim. But the options I can think of are not great.
Uploading an entire list of cached resources probably isn't feasible (and probably not possible or a privacy concern).
You could maybe do a bloom filter but probably still have privacy concerns.
There is a solution that mostly works. You can use cookies! A simple solution might be setting a cookie for the app version when you respond. On the next request you can avoid pushing resources that haven't changed between the client's last version and the current one. Or you can even try to set cookies for each asset, however I'm not sure that is a good strategy.
But this is still not perfect. The presence of the cookie doesn't mean the resource was ever downloaded (maybe it was aborted partway though?) and things can get purged from the cache and the cookie has no way of knowing.
You can also try to do out-of-band info. For example storing in a database which resources the client has downloaded before and a bunch of heuristics to determine if they are likely still in the cache. But at the end of the day only the client knows that.
So the TL;DR is I'm not sure this is possible. You are looking for `required resources - cached resources` and since `cached resources` is sensitive and probably much larger it is way easier to do this computation on the client.
So TL;DR it might be possible but is very tricky. The current state-of-the art isn't anywhere near a perfect solution.
So you have two options:
1. Pessimistically start pushing the response, and stop if the client tells you it is already cached
2. Optimistically don't push the response until the client tells you that it doesn't have it cached.
The first option is what push does.
The second option is basically equivalent to sending a `Link: <..> rel=preload` header.
So I guess one way to look at is that we had both choices available. But it turns out that Push wasn't used much and probably isn't the best option.