Using the Options Select Widget for entity reference fields can have a huge impact on memory usage, especially when there are large numbers of referenced entities.
As an example, on one content type my memory usage is about 81.5MB per page load when I go to the node/add page when I use an Autocomplete widget for a field with a particularly large option list. That jumps up to 371.25MB when I switch over to the Option Select widget.
For my personal use case, I can just switch over to the Autocomplete for a work-around. However, this seems like an issue that needs to be addressed.
Looking at the source code, it looks like the full entity is getting loaded when generating the options list.
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
$element += array(
'#type' => 'select',
'#options' => $this->getOptions($items->getEntity()),
'#default_value' => $this->getSelectedOptions($items),
// Do not display a 'multiple' select box if there is only one option.
'#multiple' => $this->multiple && count($this->options) > 1,
);
return $element;
}
Maybe it be possible to improve performance by just loading the Entity Label instead?
Comments
Comment #4
tra.duong CreditAttribution: tra.duong commentedI have a similar situation today. I have a list around 1800 nodes and increasing.
in
\core\lib\Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection.php
Line 350. A call to$entities = $this->entityTypeManager->getStorage($target_type)->loadMultiple($result);
to get an array of completes entity just to reproduce an array of entity id and translation label from it is a big wasted.
Drupal core version: 8.8.4
Comment #5
amateescu CreditAttribution: amateescu as a volunteer commentedThis is by design, in order to get the translated label of an entity we need to load the full entity object. And it's also the reason why the autocomplete widget exists :)
Comment #6
donquixote CreditAttribution: donquixote at European Commission and European Union Institutions, Agencies and Bodies commentedIt is generally not needed to load all entities into memory at once.
To get a translated title while saving memory, we can/could/should load and "forget" the entities one by one.
We could also cache individual translated entity labels, and complete option lists.
(This needs cache metadata to deliver different filtered option lists based on user permissions.)
I don't see a "reopen" button here, but it would be appropriate.
Comment #7
donquixote CreditAttribution: donquixote at European Commission and European Union Institutions, Agencies and Bodies commentedActually I _can_ reopen it!
The only case when we should close it is if we decide to open a new issue, or find one.
Comment #8
donquixote CreditAttribution: donquixote at European Commission and European Union Institutions, Agencies and Bodies commentedComment #9
donquixote CreditAttribution: donquixote at European Commission and European Union Institutions, Agencies and Bodies commentedI was going to switch a lot of widgets to autocomplete on a big site I work on.
Unfortunately this can come with some usability limitations.
Currently we use https://www.drupal.org/project/slim_select which works for select widgets but not autocomplete widgets, because it does all the magic on client side.
I can imagine a similar widget could be created for autocomplete, but I have not found one yet.
Also, having the full option list on client side will make the UI more snappy as it avoids the need for ajax requests.
There is a middle ground of ~250 options, where we want a select list with optimized loading, rather than repeated autocomplete ajax requests. E.g. a country dropdown could have this order of magnitude of options.
Comment #10
donquixote CreditAttribution: donquixote at European Commission and European Union Institutions, Agencies and Bodies commentedComment #11
quietone CreditAttribution: quietone at PreviousNext commentedThis is on Version 8.9.x which is End of Life. Moving to 11.x