Page MenuHomePhabricator

Performance: VisualEditor's template dialog is extremely slow on large templates/transclusions
Closed, ResolvedPublic

Description

It takes a very, very long time to open the template dialog for larger templates or multi-part transclusions with many templates. A trivial example with 200 undocumented parameters looks like this:

{{example
|p0=0
|p1=1
|p2=2
|p3=3
…
|p196=196
|p197=197
|p198=198
|p199=199
}}

I did a quick profile run to possibly identify some low-hanging fruits. This is how a flame graph for said 200 parameter template looks like:

Screenshot from 2021-11-24 08-06-07.png (639×1 px, 132 KB)

There are 3 big chunks in this graph:

  1. (~500ms) MWTemplateDialog.onAddParameter() is called individually for each parameter, 200 times. This creates the corresponding MWParameterPage and calls .addPages(), 200 times. There is no single bottleneck. It's just so much to do. Still there are some ideas how this could be optimized:
    • Change the relevant events so that .addPages() is only called a single time, with an array of all 200 parameters.
    • Initialize a multi-part transclusion in a collapsed state where only the top-level template names are visible, but no parameters. The MWParameterPages are created when the user clicks the template name the first time.
    • …?
  2. (~400ms) TextInputWidget.installParentChangeDetector() is called 200 times.
    • What is this for? Can we optimize the existing code, e.g. running it on an array of elements instead of individually for each element (similar to above)? Can we delay the call even more?
    • …?
  3. (~300ms) MWExpandableContentElement.updateSize() is called 200 times.
    • Must be skipped when it's not needed anyway. Done.
    • When it's needed, can we delay it somehow? Can we optimize the code, e.g. to do much cheaper calculations when the text is known to be short?
    • …?

Event Timeline

Change 740925 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[oojs/ui@master] Optimize OutlineOptionWidget.setLevel() for performance

https://gerrit.wikimedia.org/r/740925

Change 740924 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[oojs/ui@master] Skip meaningless default TextInputWidget validation

https://gerrit.wikimedia.org/r/740924

Change 740904 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[oojs/ui@master] Fix performance leak in RequiredElement constructor

https://gerrit.wikimedia.org/r/740904

Change 740891 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[mediawiki/extensions/VisualEditor@master] Performance: Don't add empty action <div>s to template dialog

https://gerrit.wikimedia.org/r/740891

Change 740889 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[mediawiki/extensions/VisualEditor@master] Performance: Don't add empty parameter descriptions to dialog

https://gerrit.wikimedia.org/r/740889

Change 741860 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[oojs/ui@master] Dramatically simplify IconElement.setIcon()

https://gerrit.wikimedia.org/r/741860

Change the relevant events so that .addPages() is only called a single time […]

I gave this a quick try. The runtime of the first section goes down from ~500ms to 375ms. That's not a landslide, but not bad either.

The experiment also shows that the parameter page constructors are what makes this section expensive. The constructors consume 3/4 of said 375ms, while the single .addPages() call is done in the remaining 1/4.

Note that almost all of the time spend in .addPages() is wasted on creating the items for the old sidebar. These items are entirely invisible, but still needed for some features (most notably the bottom toolbar). Luckily this is not a bottleneck, according to these tests. I tried to optimize it a bit by skipping the mostly pointless MWParameterPage.setupOutlineItem(), but this improved the situation only by ~30ms.

awight subscribed.

Moving into the sprint because there are patches to review, setting to "Low" priority to reflect that these are nice-to-have improvements.

[…] these are nice-to-have improvements.

The only exception is https://gerrit.wikimedia.org/r/740889, which I would classify as an actual bugfix because of the impact it has.

Change 741860 merged by jenkins-bot:

[oojs/ui@master] Dramatically simplify IconElement.setIcon()

https://gerrit.wikimedia.org/r/741860

Change 740904 merged by jenkins-bot:

[oojs/ui@master] Improve performance of RequiredElement constructor

https://gerrit.wikimedia.org/r/740904

Change 740924 merged by jenkins-bot:

[oojs/ui@master] Skip meaningless default TextInputWidget validation

https://gerrit.wikimedia.org/r/740924

Change 740925 merged by jenkins-bot:

[oojs/ui@master] Optimize OutlineOptionWidget.setLevel() for performance

https://gerrit.wikimedia.org/r/740925

Change 740889 merged by jenkins-bot:

[mediawiki/extensions/VisualEditor@master] Performance: Don't add empty parameter descriptions to dialog

https://gerrit.wikimedia.org/r/740889

Change 740891 merged by jenkins-bot:

[mediawiki/extensions/VisualEditor@master] Performance: Don't add empty action <div>s to template dialog

https://gerrit.wikimedia.org/r/740891

Change 742769 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[oojs/ui@master] Avoid more code duplication in RequiredElement mixin

https://gerrit.wikimedia.org/r/742769

Change 742769 merged by jenkins-bot:

[oojs/ui@master] Avoid more code duplication in RequiredElement mixin

https://gerrit.wikimedia.org/r/742769

Change 743466 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[oojs/ui@master] Optimize TextInputWidget.installParentChangeDetector() a bit

https://gerrit.wikimedia.org/r/743466

Change 744052 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[mediawiki/extensions/VisualEditor@master] Remove obsolete performance bottleneck from TransclusionModel

https://gerrit.wikimedia.org/r/744052

Change 744069 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):

[mediawiki/extensions/VisualEditor@master] Delay initialization of all invisible \"add parameter\" components

https://gerrit.wikimedia.org/r/744069

Change 743466 merged by jenkins-bot:

[oojs/ui@master] Optimize TextInputWidget.installParentChangeDetector() a bit

https://gerrit.wikimedia.org/r/743466

Change 744069 merged by jenkins-bot:

[mediawiki/extensions/VisualEditor@master] Delay initialization of all invisible \"add parameter\" components

https://gerrit.wikimedia.org/r/744069

Change 744052 merged by jenkins-bot:

[mediawiki/extensions/VisualEditor@master] Remove obsolete performance bottleneck from TransclusionModel

https://gerrit.wikimedia.org/r/744052

thiemowmde claimed this task.

I made a new build of OOUI, copied it to core and repeated my original benchmark. Old at the top, new at the bottom.

Screenshot from 2021-11-25 16-12-55.png (621×1 px, 140 KB)

Screenshot from 2022-01-06 12-58-32.png (576×1 px, 115 KB)

Findings:

  • Just from observation it feels much, much faster.
  • Chunk #1 (~500ms) looks the same. While several improvements have been made here their effect is hard to measure. Averaging a few runs makes it look like we are up to 10% faster here.
  • Chunk #2 went down from ~400ms to ~200ms. This is the patch that's mainly responsible for this.
  • Chunk #3 (~300ms) is just gone because of this patch.
  • The custom "templates-measure" time described in T296386#7528334 goes down from 1.5s to 0.9s.
  • The "total blocking time" as reported by Chrome goes down from ~1.0s to ~0.6s.

Overall it's now as fast as the old dialog, if not faster.

Outstanding, thanks for this thorough investigation!

Change 753557 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Update OOUI to v0.43.0

https://gerrit.wikimedia.org/r/753557

Change 753557 merged by jenkins-bot:

[mediawiki/core@master] Update OOUI to v0.43.0

https://gerrit.wikimedia.org/r/753557