This is still missing (or working unexpectedly) in TYPO3 8.7.10.
I am not sure, how to fix this correctly without breaking something else. I think, the main problem is, that the hooks are called at different times of the page generation, depending if the page has uncached objects or not. Also: Depending of *_INT-objects, different page-content will be saved to the page-cache.
When there are no uncached objects (no COA_INT and no USER_INT), then the hooks get called before getPreparedMarkerArray is called: PageRenderer.php#L1752
But when there are *_INT objects, getPreparedMarkerArrayForPageWithUncachedObjects is called before the hooks are called: PageRenderer.php#L1775.
Regarding the different cache entries:
Case 1 (No *_INT objects): The Markers are replaced BEFORE the page gets written to the cache:
<link rel="shortcut icon" href="/fileadmin/favicon.ico" type="image/x-icon">
<title>Publications: Example Page</title>
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
<link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/android-icon-192x192.png" sizes="192x192">
<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="/manifest.json">
<meta name="generator" content="TYPO3 CMS">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="/fileadmin/example.css?1519038072">
<script src="/fileadmin/script/lib/modernizr-3.5.0.min.js?1508489033"></script>
Case 2 with a single *_INT-objects:
page.20 = USER_INT
You get the markers within the cached code and everytime the page is shown from cache, the markers again:
<link rel="shortcut icon" href="/fileadmin/favicon.ico" type="image/x-icon">
<!-- ###TITLE8338e3386b101f1e83037c18ea41f85c### -->
<!-- ###META8338e3386b101f1e83037c18ea41f85c### -->
<!-- ###CSS_LIBS8338e3386b101f1e83037c18ea41f85c### -->
<!-- ###CSS_INCLUDE8338e3386b101f1e83037c18ea41f85c### -->
<!-- ###CSS_INLINE8338e3386b101f1e83037c18ea41f85c### -->
<!-- ###JS_LIBS8338e3386b101f1e83037c18ea41f85c### -->
<!-- ###JS_INCLUDE8338e3386b101f1e83037c18ea41f85c### -->
<!-- ###JS_INLINE8338e3386b101f1e83037c18ea41f85c### -->
I think it would be better to always cache a page with the unreplaced markers but to call the hooks before replacing the markers. That way it's possible to update the cache buster when getting a page from cache. But: It will be a bit slower, because the markers are replaced everytime a page is requested.
Currently the Cache-Buster of Scripts and CSS does not get updated, if a page is loaded from cache and had no *_INT-objects. But it's possible to change the shortcutTag or favIcon in hooks called from executePostRenderHook:
PageRenderer.php#L2761
But if a page had *_INT-objects, the cache buster of Scripts and CSS gets updated BUT the favIcon or shortcutTag of executePostRenderHook cannot be replaced...