Problem/Motivation
Rendering entity fields in views works like the following:
For reach row, and for each entity field execute the following code:
<?php
$entity->$field_name->view();
?>
This creates a lot of temporary objects, as some benchmarks here and in #2342045: Standard views base fields need to use same rendering as Field UI fields, for formatting, access checking, and translation consistency has shown.
Proposed resolution
Based on #1852966: Rework entity display settings around EntityDisplay config entity views could use the entityDisplay object to render with better performance.
Basically, the idea is a View should :
- run its query
- load the corresponding entities, and group them by bundle
- for each bundle
- create a runtime EntityViewDisplay object, and configure it with
->setComponent()
on each of the N fields it needs to display. This happens only once (per bundle) - render the entities in one pass:
$output[$bundle] = $display[$bundle]->buildMultiple($entities[$bundle])
- create a runtime EntityViewDisplay object, and configure it with
- for each row/entity and each field in the row, pick the output of the field in the $output array:
$field_output = $output[$entity->bundle()][$entity->id()][$field_name]
In practice, this is a bit more complicated because :
- views relationships means one row possibly involves several entities of various types, so you need to create as many Displays as there are entity types involved in one row
- Views containing multiple time the same field, but with different delta settings (just show the first delta, but also show all the other ones). For them
we filter out the unused items right before outputting the render array in views.
Remaining tasks
User interface changes
API changes
Additional method EntityViewBuilderInterface:: prepareView()