"new" and "updated" marker no longer breaking render cache
The comment "new" marker is based on the user's last viewed timestamp, which means it's forced to be per-user. That made comments only cacheable per-user. Hence it broke the render cache.
This was solved by the following measures:
- Embed metadata that is the same for all users in the HTML as
data-attributes: the node's last comment timestamp, the node's ID, the comment user ID, each comment timestamp.
localStorage) to avoid performing a HTTP request in most scenarios.
- See for a comprehensive overview of the heuristics used to minimize HTTP requests.
There are quite a few different places where this is used: comment "new" indicators, node "new comments" links, tracker "new/updated" node indicators, tracker "x new replies" links, plus use cases in the forum module. All of them should use the same heuristics and client-side caching, to prevent duplicate logic and maximize client-side cache hit ratio.
This enables entity render caching:.
History JS API
That's why there's now a new History JS API, in the
drupal.history library. It has the following methods:
needsServerCheck(nodeID, contentTimestamp: determines whether a server check is necessary. This can be used to consistently apply the heuristics. Any content that is >30 days old never gets a "new" or "updated" indicator, because it is assumed to have been read already. Any content that was published before the known "last read" timestamp (as cached in
localStorage) also is assumed to have been read already.
In other words: old content and content that's already been read can be ignored completely if this function returns
fetchTimestamps(nodeIDs, callback): fetches the "last read" timestamps for the given nodes, stores them in
localStorageand calls the callback, which can then call
getLastRead(nodeID). You should only pass in node IDs for which
true— i.e. the node IDs that need a server check.
getLastRead(nodeID): gets the "last read" timestamp for the given node, as stored in
localStorage. Should be called after
fetchTimestamps()has done its thing and called the callback.
markAsRead(nodeID): to mark the given node as read on the server side; automatically updates the client-side cache (to minimize HTTP requests further).
Look at the
drupal.node-new-comments-link libraries for sample code that uses the History JS API.
User-specific styling ("comment by viewer") no longer breaking render cache
drupal.comment-by-viewer library), that combined with a
data-comment-user-id attribute on each comment and a new
drupalSettings.user.uid setting knows whether the current user is also the commenter.