From: Alexander Ebert Date: Mon, 12 Apr 2021 17:20:54 +0000 (+0200) Subject: Avoid live updates to DOMNodeList X-Git-Tag: 5.3.6~9^2~5 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=7d9a17172d56f34ee3f1972d495703c2f9b07aa0;p=GitHub%2FWoltLab%2FWCF.git Avoid live updates to DOMNodeList The DOMNodeList is a live collection that is updated whenever an item is removed. This can have a significant performance impact when removing a large set of nodes. --- diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php index 86160cb32e..866ba51c1f 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php @@ -99,10 +99,14 @@ class HtmlOutputNodeProcessor extends AbstractHtmlNodeProcessor { if ($this->outputType !== 'text/html') { // convert `

...

` into `...

` - $paragraphs = $this->getDocument()->getElementsByTagName('p'); - while ($paragraphs->length) { - $paragraph = $paragraphs->item(0); - + $paragraphs = []; + // The DOMNodeList returned by `getElementsByTagName()` is live, causing a performance + // penalty when modifying it a lot. + foreach ($this->getDocument()->getElementsByTagName('p') as $node) { + $paragraphs[] = $node; + } + + foreach ($paragraphs as $paragraph) { $isLastNode = true; $sibling = $paragraph; while ($sibling = $sibling->nextSibling) { @@ -143,6 +147,7 @@ class HtmlOutputNodeProcessor extends AbstractHtmlNodeProcessor { DOMUtil::removeNode($paragraph, true); } + unset($paragraphs); if ($this->outputType === 'text/plain') { // remove all `\n` first