Problem/Motivation

SourcePluginBase::label(TRUE) needs one label, but reads it from getChoices(), which builds every choice.
On a derivable context source that instantiates every derivable context and resolves its sources, and on ComponentSource it sorts and negotiates every component.
Component form summaries call it for each prop, and a builder labels every node.

Measured in Display Builder, assertions off: the derivable context lookup took an article display's Canvas build from 440 to 103 ms, the component lookup a 2690-node page from 700 to 590 ms.

Steps to reproduce

  1. Open a component form whose props use field sources, or whose slots hold components.
  2. Profile it: each prop summary calls label(TRUE), which builds the full choice list.

Proposed resolution

label() keeps the $with_context check and the fallback to the plugin label, and asks a new protected getChoiceLabel() for the chosen label. By default it reads getChoices(), as before. DerivableContextSourceBase overrides it to check the chosen derivable context only, with the check extracted from listCompatibleDerivableContexts() as isCompatibleDerivableContext(). ComponentSource overrides it to negotiate the chosen component only.
Labels stay the same, and kernel tests compare them with the full lookup. The static cache of prop source lists moved to #3631243: Improve static caches : one mechanism, emptied with the definitions.

Remaining tasks

  • Review.

User interface changes

None.

API changes

New protected methods SourcePluginBase::getChoiceLabel() and DerivableContextSourceBase::isCompatibleDerivableContext().

Data model changes

None.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mogtofu33 created an issue. See original summary.

mogtofu33’s picture

Status: Needs work » Needs review
mogtofu33’s picture

Some performance benchmark for Display Builder in this comment

mogtofu33’s picture

Issue tags: +display builder
mogtofu33’s picture

just_like_good_vibes’s picture

Status: Needs review » Needs work

hello,
we have different independent changes here :
(a) changes about the labels
(b) changes about caching context matches.

and the numbers you have provided do not give details about the gain of each part.

for (a), this proposition may deserve a more generic and elegant fix instead of patching manually different sources. Indeed,
SourcePluginBase::label(TRUE) needs one label, but builds every choice through getChoices() to get it. Every source that implements SourceWithChoicesInterface pays for that.

i proposed a Generic version. label() stays the only place that does the $with_context check and the fallback. It asks one overridable method for the chosen label, something like that :

// SourcePluginBase
public function label(bool $with_context = FALSE): string {
  if ($with_context && $this instanceof SourceWithChoicesInterface) {
    $choice_id = $this->getChoice($this->settings);
    $label = $choice_id ? $this->getChoiceLabel($choice_id) : NULL;
    if ($label !== NULL) {
      return $label;
    }
  }
  return /* plugin label, unchanged */;
}

protected function getChoiceLabel(string $choice_id): ?string {
  $label = $this->getChoices()[$choice_id]['label'] ?? NULL;
  return $label === NULL ? NULL : (string) $label;
}

ComponentSource and DerivableContextSourceBase would override only getChoiceLabel(), with their one-choice lookup. LayoutSource could do the same later.

(b) i opened a new separate issue #3631243: Improve static caches : one mechanism, emptied with the definitions to tackle static caches improvement, i will personally address that. in the meantime, could you remove that part from the current proposition and stick to the label part.

thank you

mogtofu33’s picture

Issue summary: View changes
Status: Needs work » Needs review
Related issues: +#3631243: Improve static caches : one mechanism, emptied with the definitions

Hello,
Cache removed, generic getChoiceLabel() as proposed, the instanceof guard, numbers per part in the summary of the issue.

mogtofu33’s picture

Issue summary: View changes