Views entity rendering should use a lazy builder/placeholder

Created on 11 April 2025, 11 days ago

Problem/Motivation

The RenderedEntity plugin in views currently looks like this:

  /**
   * {@inheritdoc}
   */
  public function render(ResultRow $values) {
    $entity = $this->getEntity($values);
    if ($entity === NULL) {
      return '';
    }
    $entity = $this->getEntityTranslationByRelationship($entity, $values);
    $build = [];
    $access = $entity->access('view', NULL, TRUE);
    $build['#access'] = $access;
    if ($access->isAllowed()) {
      $view_builder = $this->entityTypeManager->getViewBuilder($this->getEntityTypeId());
      $build += $view_builder->view($entity, $this->options['view_mode'], $entity->language()->getId());
    } 
    return $build;
  }

If possible, we should move this into a lazy_builder/placeholder.

The results of this will be most noticeable with 📌 Try to replace path alias preloading with lazy generation Active because it will allow e.g. the path aliases for all ten nodes in a node listing to be preloaded including on complete cache misses, but it's likely to have other benefits too - for example render cache entries for views listings will just have a placeholder instead of the actual entity HTML which should reduce cache size.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

📌 Task
Status

Active

Version

11.0 🔥

Component

views.module

Created by

🇬🇧United Kingdom catch

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

Merge Requests

Comments & Activities

  • Issue created by @catch
  • 🇬🇧United Kingdom catch

    To make this work, should look something like this:

    - we need to get the entity ID + langcode in the plugin to pass to the lazy builder, this can be done by slightly reworking/copying getEntityTranslationByRelationship().

    - a new service providing the lazy builder callback itself, which takes the entity id + langcode, loads the entity/translation and renders it.

  • 🇨🇭Switzerland berdir Switzerland

    I thought about this, but I'm not quite sure if this is really the right thing to do.

    This would pull all these entities out of dynamic page cache as well, is that really what we want to do? Maybe, but also seems to have fairly big implications that we should carefully think through.

    should we also exclude them from bigpipe by default?

    for views in blocks, this will result in placeholders within placeholders?

    what about entity references, comments?

    some entities might be not be cacheable, that could be costly. People do use views to render paragraphs for example more often than I'd like.

  • 🇬🇧United Kingdom catch

    This would pull all these entities out of dynamic page cache as well, is that really what we want to do?

    Generally the entity view itself gets render cached, and that will get multiple loaded by CachedPlaceholderStrategy, so it ought to be OK.

    some entities might be not be cacheable, that could be costly. People do use views to render paragraphs for example more often than I'd like.

    But... not in this case and I hadn't thought about that.

    Another way to approach this would to render the entities (or more likely views rows) within fibers but not placeholders.

    A bit like 📌 Render children in fibers Active although assuming we'll try to avoid doing that actually issue.

  • 🇬🇧United Kingdom catch

    Looks like StylePluginBase::renderGroupingSets() is the place to try using Fibers, which should produce the same result with path alias preloading but without actual placeholdering.

  • 🇬🇧United Kingdom catch
  • 🇬🇧United Kingdom catch
  • 🇬🇧United Kingdom catch
  • Merge request !11811Render views rows in fibers. → (Open) created by catch
  • 🇬🇧United Kingdom catch
  • 🇬🇧United Kingdom catch

    Pushed a branch with a couple of commits, needs cleaning up but it works in combination with 📌 Try to replace path alias preloading with lazy generation Active to preload all the aliases rendered within views rows.

  • 🇬🇧United Kingdom catch

    The test failures are (mostly? all?) due to known issues - added to issue summary.

Production build 0.71.5 2024