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

nplowman created an issue. See original summary.

Version: 8.2.4 » 8.2.x-dev

Core issues are now filed against the dev versions where changes will be made. Document the specific release you are using in your issue comment. More information about choosing a version.

Version: 8.2.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Branches prior to 8.8.x are not supported, and Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

tra.duong’s picture

I 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

amateescu’s picture

Status: Active » Closed (works as designed)
Issue tags: -Performance, -widget, -select, -Entity Reference

This 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 :)

donquixote’s picture

This 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 :)

It 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.

donquixote’s picture

Status: Closed (works as designed) » Active

Actually I _can_ reopen it!
The only case when we should close it is if we decide to open a new issue, or find one.

donquixote’s picture

And it's also the reason why the autocomplete widget exists :)

I 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.

quietone’s picture

Version: 8.9.x-dev » 11.x-dev

This is on Version 8.9.x which is End of Life. Moving to 11.x