Add an option to pass through caching for instances implementing CacheableDependencyInterface

Created on 9 May 2017, almost 8 years ago
Updated 23 March 2025, 10 days ago

Problem/Motivation

It seems that, in general, renderable components and/or plugins like blocks and field items are generally limited regarding reusing instances of them on the same page multiple times, due to the behavior of the caching system. All objects holding renderable data and implementing CacheableDependencyInterface seem to be affected by this. I'm trying to describe the limitation with the following simplified example:

A given render array (element) represents an HTML tag with a unique HTML id being randomly generated.
The only requirement of the element is, that it must have a unique HTML id when it's being rendered.
The element will be returned by a block plugin, i.e. a class which implements BlockPluginInterface.
The block plugin does not depend or relate on any data / configuration of the system, i.e. no users, no nodes, no URL etc - it's just there to output the element.
The only requirement of the block plugin is, that an instance of it must be globally reusable.

An instance of the block has been created and placed via the block layout.
A node of a certain type has an entity reference field to blocks. The teaser mode of the node outputs the entity reference field.
There are now multiple nodes which reference to the same block instance. A view on a page lists these nodes in teaser view mode.
In the list, the block outputs the element multiple times, but cached. As a result, the HTML id is not unique and thus doesn't meet its corresponding requirement.

A way to meet both requirements (from element and block plugin) is to set the block plugin's max-age cache to 0. This means that the block doesn't allow any caching. Because of the render cache's "bubbling" behavior, this would imply that all parent render elements won't be cacheable. This means, when an instance of the block plugin is getting rendered inside a field item, all the field items, the whole teaser view, the whole list view, the region where this list view is getting rendered and its further parents won't be cacheable in the render cache.

For block plugins, you could use hook_block_build_alter() to remove its generated cache key for "passing through" the render array. This can be useful e.g. for blocks which

  • are cheap to render and
  • most likely have invalid cache records when their parent elements have invalid cache records

Proposed resolution

Enable objects implementing CacheableDependencyInterface to deliver some sort of cache passthrough, i.e. they just take the bubbled caching metadata from their child elements and pass them through (or say "bubble up") to their parent elements. This way, these objects are just further parts of the whole render structure, but their parent elements (in the above example the field items, teaser view mode, list views and regions etc.) may be still cacheable.

I'm not sure whether it's clear what I've written here. Feel free to ask for more details. Of course it's also possible that I miss or misunderstood an important part of the caching system here.

Feature request
Status

Closed: duplicate

Version

11.0 🔥

Component

cache system

Created by

🇩🇪Germany mxh Offenburg

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇨🇭Switzerland berdir Switzerland

    I'm going ahead and closing this as a duplicate, see all the issues that were recently worked on in 11.2, specifically the children of 🌱 Optimize render caching Needs work .

    Blocks can now force a lazy builder placeholder, and we have the ability to bulk-load them from render cache, we have CacheOptionalInterface and either 📌 Make language switcher block cacheable Postponed or a spin off of that (if it doesn't happen there, we could reopen this) will implement support for respecting that in BlockViewBuilder.

Production build 0.71.5 2024