Problem/Motivation

#2552873: node/1 flamegraphs uncovered that EditorManager::getAttachments() is ridiculously expensive.

This is because the comment form loads all editors at once, in order to show only one editor.

Proposed resolution

Either cache the result, or only load one editor in editor_load().

Remaining tasks

Profile node/1 with comments enabled, confirm this is still an issue and compare the two proposed approaches.

User interface changes

None.

API changes

None.

Data model changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers created an issue. See original summary.

Wim Leers’s picture

Issue summary: View changes
Status: Active » Needs review
FileSize
3.92 KB

Status: Needs review » Needs work

The last submitted patch, 2: cache_editormanager_getattachments-2553695-2.patch, failed testing.

Wim Leers’s picture

Issue tags: +Novice, +php-novice
dawehner’s picture

+++ b/core/modules/editor/src/Plugin/EditorManager.php
@@ -64,6 +76,32 @@ public function listOptions() {
+      foreach ($format_ids as $format_id) {
+        $editor = editor_load($format_id);
+        if (!$editor) {
+          continue;
+        }
+      }

I'm sorry but this piece of code is confusing ... does that do anything? In case it does, it feels magic for me, at least add a comment.

Wim Leers’s picture

#5: Yeah, it sucks. But it's the same as the other code in that file, where it is copied from. Not every text format has a text editor associated with it. That if-statement is there in case the text format does not have a text editor.

Wim Leers’s picture

  1. +++ b/core/modules/editor/src/Plugin/EditorManager.php
    @@ -64,6 +76,32 @@ public function listOptions() {
    +      $tags = ['editor_list'];
    

    We need this in case a text format that didn't have a text editor before now has one.

  2. +++ b/core/modules/editor/src/Plugin/EditorManager.php
    @@ -64,6 +76,32 @@ public function listOptions() {
    +      foreach ($format_ids as $format_id) {
    +        $editor = editor_load($format_id);
    +        if (!$editor) {
    +          continue;
    +        }
    +      }
    

    Hence all of this can be removed, because it's already implied by the list cache tag.

This then also happens to fix #5 :)

dawehner’s picture

Status: Needs work » Needs review
FileSize
4.4 KB
4.17 KB

What about fixing the actual code, and make the actual loading code not public and improve the code to even in case of a cache miss, not load invidiual entities over time ...

Wim Leers’s picture

not public

Honest oversight in a quick PoC patch ;)

not load invidiual entities over time

Please look at editor_load(), you'll see that this is untrue.

dawehner’s picture

Status: Needs review » Needs work
Issue tags: +needs profiling

As wim explained these numbers are a little bit unfair. This seems to be the first thing which loads the entity type definitions.
If this does not load it, something else might?
Let's have a profiling to see how much actually is saved.

Please look at editor_load(), you'll see that this is untrue.

OH, the fuck. I think then not using it is perfect. How likely is that we need all editors on every request?

The last submitted patch, 8: 2553695-8.patch, failed testing.

Wim Leers’s picture

OH, the fuck. I think then not using it is perfect. How likely is that we need all editors on every request?

I agree with your assessment.

This goes back to how wysiwyg module works, and IIRC sun and/or quicksketch felt very strongly back then that we should keep this pattern.

(Perhaps now they would agree that it no longer makes sense, now that D8's entity system works quite differently. I don't remember the exact reasons.)

moshe weitzman’s picture

Issue tags: +sprint
Wim Leers’s picture

Version: 8.0.x-dev » 8.1.x-dev
Issue tags: -sprint

This is a performance improvement that we can do in 8.1.x.

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

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

lokapujya’s picture

Status: Needs work » Needs review
FileSize
5.09 KB
910 bytes

Status: Needs review » Needs work

The last submitted patch, 16: 2553695-16.patch, failed testing.

lokapujya’s picture

Status: Needs work » Needs review
FileSize
775 bytes
5.85 KB

Seems this is waiting on profiling,but just looking into the fails. Why is the editor settings array different? Do the tests just need to update due to the changes in the patch? Here is an attempt.

Status: Needs review » Needs work

The last submitted patch, 18: 2553695-17.patch, failed testing.

mr.baileys’s picture

Status: Needs work » Needs review
FileSize
2.93 KB
6.32 KB

The tests are failing since they are testing hook_editor_js_settings_alter(), and the result of this hook is now cached in getAttachments(), providing the test with stale cached settings-data.

Either we move the result of altering the settings through hook_editor_js_settings_alter() outside of caching, or we include it in the cache (as I think is the default way of caching in core) and we have the test explicitly invalidate the cached attachments.

Besides the test failures, when calling EditorManager->clearCachedDefinitions(), only the definitions are cleared, while the attachments-cache remains. This seems like a bug, patch attached that ensures that the attachments-cache is cleared whenever the definitions cache is cleared by setting the editor_list cache tag on the definitions cache backend.

Wim Leers’s picture

Yay, thanks for pushing this forward! This is very very close now.

  1. +++ b/core/modules/editor/src/Plugin/EditorManager.php
    @@ -56,7 +56,7 @@ class EditorManager extends DefaultPluginManager {
    -    $this->setCacheBackend($discovery_cache, 'editor_plugins');
    +    $this->setCacheBackend($discovery_cache, 'editor_plugins', ['editor_list']);
    

    This totally makes sense!

  2. +++ b/core/modules/editor/src/Tests/EditorManagerTest.php
    @@ -10,6 +10,7 @@
    +use Drupal\Core\Cache\Cache;
    

    Not necessary.

  3. +++ b/core/modules/editor/src/Tests/EditorManagerTest.php
    @@ -109,6 +110,9 @@ public function testManager() {
    +    // Attachments are cached, so we need to clear the cache to make sure
    +    // hook_editor_js_settings_alter() is invoked.
    

    This comment is true, but the specific reason for this being problematic is the line above: it uses \Drupal::state() to cause a change in output!

    Any time a test uses state to cause different output (which is fine btw), you need to explicitly clear cache.

    I think the comment should say that.

mr.baileys’s picture

Issue tags: -Novice, -php-novice
FileSize
1.36 KB
6.12 KB

Thanks Wim! Removed the unused use statement and altered the wording on the comment.

Wim Leers’s picture

Perfect! Now all that remains is some profiling as per #10.

dawehner’s picture

Just some driveby review.

+++ b/core/modules/editor/editor.services.yml
@@ -1,7 +1,7 @@
+    arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@cache.data', '@entity.manager']
   element.editor:

+++ b/core/modules/editor/src/Plugin/EditorManager.php
@@ -22,20 +25,40 @@
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $discovery_cache, ModuleHandlerInterface $module_handler, CacheBackendInterface $attachments_cache, EntityManagerInterface $entity_manager) {

@@ -64,15 +87,33 @@ public function listOptions() {
+    $editors = $this->entityManager->getStorage('editor')->loadMultiple($format_ids);

Let's use the entity type manager.

mr.baileys’s picture

Thanks dawehner, replaced EntityManager with EntityTypeManager.

jibran’s picture

+++ b/core/modules/editor/src/Plugin/EditorManager.php
@@ -64,15 +86,33 @@ public function listOptions() {
+    $cid = 'editor_attachments:' . implode($format_ids);
+    if ($cache = $this->attachmentsCache->get($cid)) {
+      $attachments = $cache->data;
+    }

I presume we need tests for this bit of additional code.

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

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

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

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

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

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now 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.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Postponed (maintainer needs more info)
Issue tags: +Needs issue summary update

if still a valid task can we get an updated issue summary please. What exactly is being proposed to fix?

catch’s picture

Issue summary: View changes
Status: Postponed (maintainer needs more info) » Needs work
Issue tags: -Needs issue summary update

Updated the issue summary, I doubt anything much has changed here looking at editor_load() in 9.5.x, so probably original findings are valid but we'll need to validate.

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

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.