From 129f460878d576b73f1e29ef7e349cd5587910d5 Mon Sep 17 00:00:00 2001 From: David Liu Date: Tue, 3 Sep 2024 21:14:16 -0400 Subject: [PATCH] Improve textviewer rendering speed --- Changelog.md | 2 + .../Components/Result/text_viewer.jsx | 75 +++++++------------ 2 files changed, 27 insertions(+), 50 deletions(-) diff --git a/Changelog.md b/Changelog.md index f7860a3b41..e827001a89 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,8 @@ ### ✨ New features and improvements +- Improve textviewer rendering speed (#7211) + ### 🐛 Bug fixes ### 🔧 Internal changes diff --git a/app/assets/javascripts/Components/Result/text_viewer.jsx b/app/assets/javascripts/Components/Result/text_viewer.jsx index b3fad2514d..98e82d3476 100644 --- a/app/assets/javascripts/Components/Result/text_viewer.jsx +++ b/app/assets/javascripts/Components/Result/text_viewer.jsx @@ -65,65 +65,40 @@ export class TextViewer extends React.PureComponent { run_syntax_highlighting = () => { Prism.highlightElement(this.raw_content.current, false); + let nodeLines = []; let currLine = document.createElement("span"); currLine.classList.add("source-line"); + let currChildren = []; for (let node of this.raw_content.current.childNodes) { - if (node.nodeType === Node.TEXT_NODE) { - // SourceCodeLine.glow assumes text nodes are wrapped in elements - let textContainer = document.createElement("span"); - let textNode = null; - if (node.textContent.includes("\n")) { - const splits = node.textContent.split("\n"); - for (let i = 0; i < splits.length - 1; i++) { - textNode = document.createTextNode(splits[i] + "\n"); - textContainer.appendChild(textNode); - currLine.appendChild(textContainer); - nodeLines.push(currLine); - currLine = document.createElement("span"); - currLine.classList.add("source-line"); - textContainer = document.createElement("span"); - } - textNode = document.createTextNode(splits[splits.length - 1]); - } else { - textNode = node.cloneNode(true); - } - textContainer.appendChild(textNode); - currLine.appendChild(textContainer); - } else { - if (node.textContent.includes("\n")) { - const splits = node.textContent.split("\n"); - let textContainer = document.createElement("span"); - textContainer.className = node.className; - let textNode = null; - for (let i = 0; i < splits.length - 1; i++) { - textNode = document.createTextNode(splits[i] + "\n"); - textContainer.appendChild(textNode); - currLine.appendChild(textContainer); - nodeLines.push(currLine); - currLine = document.createElement("span"); - currLine.classList.add("source-line"); - textContainer = document.createElement("span"); - textContainer.className = node.className; - } - textNode = document.createTextNode(splits[splits.length - 1]); - textContainer.appendChild(textNode); - currLine.appendChild(textContainer); - } else { - currLine.appendChild(node.cloneNode(true)); - } + const splits = node.textContent.split("\n"); + + // Note: SourceCodeLine.glow assumes text nodes are wrapped in elements + let textContainer = document.createElement("span"); + let className = node.nodeType === Node.TEXT_NODE ? "" : node.className; + textContainer.className = className; + + for (let i = 0; i < splits.length - 1; i++) { + textContainer.textContent = splits[i] + "\n"; + currLine.append(...currChildren, textContainer); + nodeLines.push(currLine); + currLine = document.createElement("span"); + currLine.classList.add("source-line"); + currChildren = []; + textContainer = document.createElement("span"); + textContainer.className = className; } + + textContainer.textContent = splits[splits.length - 1]; + currLine.append(...currChildren, textContainer); } if (currLine.textContent.length > 0) { nodeLines.push(currLine); } - nodeLines.push(this.raw_content.current.lastChild.cloneNode(true)); - while (this.raw_content.current.firstChild) { - this.raw_content.current.removeChild(this.raw_content.current.lastChild); - } - for (let n of nodeLines) { - this.raw_content.current.appendChild(n); - } + this.raw_content.current.replaceChildren( + ...nodeLines, + this.raw_content.current.lastChild.cloneNode(true) + ); }; change_font_size = delta => {