Updated: Comment #83
Blocks having their own caching system is obsolete as of
- We should remove the Block Cache system, since it's just a shorthand/abstraction for render caching.
- We should make blocks set the appropriate cache tags, so that they can use the same render cache invalidation mechanism as everything else.
- (#6) We should not force block implementers to deal with the implementation details of leveraging the render cache maximally: setting
#cacheis easy, putting the expensive computations in
#pre_renderis not. In other words: keep the Block API simple, and make it use render cache automatically (block plugins implement a
build()method to build a render array of what they represent, and that's basically it).
- Ideally (in the spirit of "Fast by default"), we will eventually be able to make as many blocks as possible in Drupal core cacheable forevery by default. Thanks to cache tags, that's feasible: cache a rendered block forever (
Cache::PERMANENT), until one of its cache tags is invalidated. That's it!
Note that in case of complex needs for sites with e.g. highly dynamic (e.g. time-dependent)
hook_entity_access()implementations, it's trivial to disable caching: just change the default "Cache: Maximum age" setting on a block from "Forever" to "zero seconds"! I.e.: opt-out as a default, therefore fast by default.
To be able to do that for a given block plugin, it must have test coverage to ensure that its cache tags are indeed invalidated in all necessary cases. The first examples for which we are able to do this, are the
SystemMenuBlock(#62) (thanks to the test coverage added in ),
CustomBlockBlock(#106) blocks (thanks to ), and
- (#85) Furthermore, admin users should be able to specify the cache contexts that a cached block should be varied by. This empowers them to cache most blocks.
- While the above ("make blocks cacheable forever") may seem like it's out of scope, it's really part of the necessary API validation.
For more screenshots, see #96. This is what it looks like overall:
For profiling, see #124. The short version:
- Make as many blocks as possible cached forever by default.
User interface changes
- Blocks now have a "Maximum age" setting, which is a
<select>with the same options as the "Page cache maximum age" setting.
- Blocks now have a "Vary by context" setting, which is a set of checkboxes of available contexts.
- Block caching is removed from the Views UI. Views keeps its time and tag based caching.
- Blocks no longer declare a cache strategy. Instead, they implement
CacheableInterface, for which
BlockBasesets sane defaults, but which each block plugin may override. E.g. by default, there is no cache granularity, but a menu block may declare itself to be cacheable per page and per role.
- There is a new
@cache_contextsservice that looks for tagged "cache context" services and makes those cache contexts available to the entire Drupal caching system. Drupal core will ship with:
LanguageCacheContext), cfr. the old implicit per-language-if-multiple-available caching of blocks)
ThemeCacheContext), cfr. the old implicit per-theme caching of blocks)
- Query-dependent cache keys can now be generated using
- Consequently, the old block cache API and related functions are now removed: the old constants, and the
- A block's "cache" property is no longer set to to "enabled" (1) or "disabled" (-1), but has a
max_ageproperty now, that defaults to
0(as in "this block may be cached for zero seconds"). It also has a
contextsproperty, which allows the user to specify cache contexts the block should be varied by.
- Significantly simplified block rendering logic.
Cache::PERMANENT === -1instead of
Cache::PERMANENT === 0
Original report by @moshe weitzman
As of, The Block Cache system is a shorthand that blocks can optionally use to get #cache set on their render arrays. That #cache array gets the proper keys on it for each block constant (e.g. DRUPAL_CACHE_PER_ROLE). The #cache array can't be further customized though, so it has no custom expire time, no custom bin, and now no custom cache tags. Especially this last limitation is the final straw.The value of the shorthand is no longer there.
Blocks should simply return render arrays, with #cache on them if they want to be cached. Only one block in all of core uses the block cache constants (book module). That block is converted to the new system without logic changes
|#132||blockcache-2158003-132.patch||126.35 KB||Wim Leers|
|PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 66,636 pass(es).|
|#80||interdiff.txt||745 bytes||Wim Leers|
|#80||blockcache-2158003-80.patch||77.83 KB||Wim Leers|
|PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 65,098 pass(es).|
|#67||blockcache-2158003-67.patch||81.11 KB||Wim Leers|
|PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 65,096 pass(es).|