Performance issue with the altSelector method in the SchemaMetatagManager class

Created on 27 January 2025, 3 months ago

Problem/Motivation

On one of our websites, one that has a lot of available metatags/groups/.., we noticed the node edit page (and a custom entity's edit page) were extremely in loading.
Through some profiling with xdebug and xhprof, I've come to the solution that the SchemaMetatagManager::altSelector method is the culprit.
In our case, it got called 512 times but caused a very noticeable 400 ms delay.
After uninstalling schema_metatag locally, the entities' edit pages were fast.

Proposed resolution

I'm not 100% certain on what a lasting/stable solution here would be, I think changing this code to the reworked snippet would already be a big step forward.

    /** @var \Drupal\metatag\MetatagManager $metatag_manager */
    $metatag_manager = \Drupal::service('metatag.manager');
    $metatag_groups = $metatag_manager->sortedGroupsWithTags();

    $group = '';
    $matches = [];
    $regex = '/:input\[name="(\w+)\[/';
    preg_match($regex, $selector, $matches);
    $id = $matches[1];
    foreach ($metatag_groups as $group_info) {
      if (!empty($group_info['tags'])) {
        if (array_key_exists($id, $group_info['tags'])) {
          $tag = $group_info['tags'][$id];
          $group = $tag['group'];
          break;
        }
      }
    }

Refreshed/reworked snippet:

  // Add a new property to the manager class.
  protected $metatagGroups;

    // Check and fill this property first, and access it directly on succeeding calls.
    if (!isset($this->metatagGroups)) {
      $metatag_manager = \Drupal::service('metatag.manager');
      $this->metatagGroups = $metatag_manager->sortedGroupsWithTags();
    }

    $group = '';
    $matches = [];
    $regex = '/:input\[name="(\w+)\[/';
    preg_match($regex, $selector, $matches);
    $id = $matches[1];
    foreach ($this->metatagGroups as $group_info) {
      if (!empty($group_info['tags'])) {
        if (array_key_exists($id, $group_info['tags'])) {
          $tag = $group_info['tags'][$id];
          $group = $tag['group'];
          break;
        }
      }
    }

But I'm open to other suggestions! 😇

📌 Task
Status

Active

Version

3.0

Component

Code

Created by

🇧🇪Belgium RandalV

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024