getViewBuilder('node')->viewMultiple() bypasses render cache

Created on 14 January 2017, about 8 years ago
Updated 16 March 2023, almost 2 years ago

There are two ways to render an entity through the Entity API

Either do

    $nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple([1]);
    $build['nodes'] = \Drupal::entityTypeManager()->getViewBuilder('node')->viewMultiple($nodes, 'teaser');

or

    $nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple([1]);
    foreach ($nodes as $node) {
      $build['nodes'][] = \Drupal::entityTypeManager()->getViewBuilder('node')->view($node, 'teaser');
    }

The problem with viewMultiple() is that render cache is bypassed in a subtle way. Even though you won't see any changes, the pre_render callback will call all entity build/view/alter hooks .. so if anything is expensive going on there, well, you're doing it again even though you have a hit.

I've attached a simple module which you can use to see the problem.

1. turn on and make sure you have a node with id 1
2. turn off page and dynamic page cache, make sure no other caching mechanism is in place
3. surf to /test
4. check that the entity is render cache
5. open testing.module and uncomment the 'die' line (line 9)
6. reload page, everything is fine
7. open src/TestController and comment the viewMultiple() line and uncomment the foreach
8. reload: wsod ..

🐛 Bug report
Status

Needs work

Version

10.1

Component
Entity 

Last updated about 12 hours ago

Created by

🇧🇪Belgium swentel

Live updates comments and jobs are added and updated live.
  • Performance

    It affects performance. It is often combined with the Needs profiling tag.

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.

  • 🇮🇳India prem suthar Ahemdabad- Gujrat , Jodhpur - Rajsthan

    Solved the #54 Custom CMD Failed Patch.
    Also, Add the Interdiff Of the 53-58 patches.

  • Status changed to Needs review almost 2 years ago
  • 🇮🇳India prem suthar Ahemdabad- Gujrat , Jodhpur - Rajsthan
  • Status changed to Needs work almost 2 years ago
  • 🇺🇸United States smustgrave

    Test coverage appears to be there (good)
    Issue summary should be updated though with proposed solution, remaining tasks, any api changes, etc.

  • 🇺🇦Ukraine nnevill Lutsk

    I'm not sure a patch is needed here.
    Just call buildMultiple() after viewMultiple():

    $build_list = $entity_type_manager
      ->getViewBuilder('node')
      ->viewMultiple($nodes, 'teaser');
    $build = $view_builder->buildMultiple($build_list);

    In this case you can apply any cache tweaks in hook_ENTITY_TYPE_view_alter().

Production build 0.71.5 2024