0

On a page controller I have a method that displays the content via a render array. It also caches the rendered output using the #cache key:

  public function viewContent(NodeInterface $node) {
    $content = array(
     '#entity' => $node,
     '#sorted' => TRUE,
     '#pre_render' => [[$this, 'buildList']],
     // Cache the render array until the lock history/node is changed.
     '#cache' => [
      'keys' => ['my_module', 'node', $node->id()],
      'tags' => ['my_module:node:' . $node->id()],
     ],
   );
    return $content;
  }

But I noticed that drupal is generating 2 cache entries per user role in the cache render table as you can see in the screenshot: enter image description here

Is it possible to generate only 1 set of entries for all users and manually pick the cid using the builtin render #cache properties?

1

Yes, by default cached render arrays are varied by the hashed user permissions. See this container parameter:

/sites/default/services.yml

parameters:
  renderer.config:
    # Renderer required cache contexts:
    #
    # The Renderer will automatically associate these cache contexts with every
    # render array, hence varying every render array by these cache contexts.
    #
    # @default ['languages:language_interface', 'theme', 'user.permissions']
    required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions']

Though this should be changed only in rare cases, because caching content with the wrong user permissions can cause security issues.

If you don't want the variations of the render cache, another approach might be to cache the query results directly:

use Drupal\Core\Cache\Cache;

  if ($cache = \Drupal::cache()->get($cid)) {
    $data = $cache->data;
  }
  else {
    $data = my_module_query();
    \Drupal::cache()->set($cid, $data, Cache::PERMANENT, $tags);
  }

Then you can manually pick a cid. With the cached query results the rendering of the list shouldn't take too much cpu time and so probably you don't need render caching anymore.

  • is it possible to achieve without changing the renderer.config: required_cache_contexts parameter? I tried using the ['contexts'] key and set it to [''] which broke it or a single context i.e. ['url.path'] but it seems drupal merge all contexts with required_cache_contexts – awm Mar 27 '18 at 16:13
  • Another idea might be to cache the query directly, see the edit. – 4k4 Mar 27 '18 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.