Reflow/repaint 问题?优化太慢的应用程序
Reflow/repaint issues? Optimize app that is way too slow
好的,所以我已经 运行 解决了我认为是优化问题的问题。我写了一个简短的应用程序,它从两个字段中获取数据,逐个字符地将它们分开并将它们相互匹配,突出显示差异。问题似乎是因为函数循环并且不仅一次打印每个字符,而且一次一个地改变新跨度中的颜色,因此大数据条目存在严重的瓶颈。甚至五个句子中的一个句子也能正常工作,但是当你翻到整页文本时,事情就会陷入困境,在某些情况下甚至会崩溃。我试图查找 repaints/reflows 的一些修复程序,但我之前没有 运行 进入这个问题并且对此了解不多。欢迎任何提示。
代码在这里:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Data Comparison</title>
</head>
<body>
<p><strong>Insert text into fields one and two and press 'Compare'. Matching data is green non-matching is red. </strong></p>
<div class="userField">
<h1>Input Field 1</h1>
<textarea id="textAreaOne" rows="30" cols="65"></textarea>
</div>
<div class="userField">
<h1>Input Field 2</h1>
<textarea id="textAreaTwo" rows="30" cols="65"></textarea>
</div>
<div id="submission">
<button onclick="compare(textAreaOne);">Compare</button>
</div>
<div id="divOne">
<h1 id="titleOne">Output Field 1</h1>
<p id="outputOne"></p>
</div>
<div id ="divTwo">
<h1 id="titleTwo">Output Field 2</h1>
<p id="outputTwo"></p>
</div>
</body>
</html>
CSS:
body {
width: 100%;
margin: 0;
padding: 0;
font-family: Verdana, Geneva, sans-serif;
font-size: 15px;
}
.userField {
display: inline-block;
width: 44%;
margin: 15px;
padding: 15px;
background-color: lightgrey;
border-radius: 13px;
box-shadow: 3px 3px 3px slategrey;
}
#submission {
text-align: center;
}
#divOne {
display: inline-block;
margin: 15px;
padding: 15px;
width: 44%;
word-wrap: break-word;
background-color: lightgrey;
}
#divTwo {
display: inline-block;
background-color: lightgrey;
width: 44%;
word-wrap: break-word;
margin: 15px;
padding: 15px;
}
#titleOne {
background-color: white;
width: 240px;
border-radius: 30px;
padding: 6px;
}
#titleTwo {
background-color: white;
width: 240px;
border-radius: 30px;
padding: 6px;
}
JS:
const fieldOne = document.querySelector("#textAreaOne");
const fieldTwo = document.querySelector("#textAreaTwo");
function compare(){
document.querySelector("#outputOne").innerHTML = "";
document.querySelector("#outputTwo").innerHTML = "";
document.querySelector("#divOne").style.visibility = "hidden";
document.querySelector("#divTwo").style.display = "hidden";
let dataOne = [];
let arrOne = fieldOne.value;
let temp = arrOne.split("");
dataOne.push(temp);
let dataTwo = [];
let arrTwo = fieldTwo.value;
let tempTwo = arrTwo.split("");
dataTwo.push(tempTwo);
if (fieldOne.value.length <= fieldTwo.value.length){
for (var i = 0; i<fieldOne.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
document.querySelector("#outputOne").innerHTML += "<span style='color:green'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:green'>" + dataTwo[0][i] + "</span>";
} else {
document.querySelector("#outputOne").innerHTML += "<span style='color:red'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldOne.value.length < fieldTwo.value.length){document.querySelector("#outputTwo").innerHTML += "<span>...</span>";}
}
else {
for (var i = 0; i<fieldTwo.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
document.querySelector("#outputOne").innerHTML += "<span style='color:green'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:green'>" + dataTwo[0][i] + "</span>";
} else {
document.querySelector("#outputOne").innerHTML += "<span style='color:red'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldTwo.value.length < fieldOne.value.length){ document.querySelector("#outputOne").innerHTML += "<span>...</span>";}
}
document.querySelector("#divOne").style.visibility = "visible";
document.querySelector("#divTwo").style.visibility = "visible";
}
https://codepen.io/Axfinger/pen/QxvbqM?editors=0010
谢谢
您的代码运行缓慢的主要原因是您不断为每个字母修改 innerHtml。
即使有多个段落,这种方法也更快:
[...]
let outOne = '';
let outTwo = '';
if (fieldOne.value.length <= fieldTwo.value.length){
for (var i = 0; i<fieldOne.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
outOne += dataOne[0][i];
outTwo += dataTwo[0][i];
} else {
outOne += "<span style='color:red'>" + dataOne[0][i] + "</span>";
outTwo += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldOne.value.length < fieldTwo.value.length){outTwo += "...";}
}
[...]
outputOne.innerHTML = outOne;
outputTwo.innerHTML = outTwo;
请注意,为了清楚起见,我省略了部分代码。
也就是说,如果您还需要更快的速度:
- 查找以将尽可能多的数据拟合到红色跨度中。那就是不同字母的整个连续子序列。
- 在 webworker 中执行该函数(将花费类似的时间,但至少不会冻结浏览器)。
好的,所以我已经 运行 解决了我认为是优化问题的问题。我写了一个简短的应用程序,它从两个字段中获取数据,逐个字符地将它们分开并将它们相互匹配,突出显示差异。问题似乎是因为函数循环并且不仅一次打印每个字符,而且一次一个地改变新跨度中的颜色,因此大数据条目存在严重的瓶颈。甚至五个句子中的一个句子也能正常工作,但是当你翻到整页文本时,事情就会陷入困境,在某些情况下甚至会崩溃。我试图查找 repaints/reflows 的一些修复程序,但我之前没有 运行 进入这个问题并且对此了解不多。欢迎任何提示。
代码在这里:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Data Comparison</title>
</head>
<body>
<p><strong>Insert text into fields one and two and press 'Compare'. Matching data is green non-matching is red. </strong></p>
<div class="userField">
<h1>Input Field 1</h1>
<textarea id="textAreaOne" rows="30" cols="65"></textarea>
</div>
<div class="userField">
<h1>Input Field 2</h1>
<textarea id="textAreaTwo" rows="30" cols="65"></textarea>
</div>
<div id="submission">
<button onclick="compare(textAreaOne);">Compare</button>
</div>
<div id="divOne">
<h1 id="titleOne">Output Field 1</h1>
<p id="outputOne"></p>
</div>
<div id ="divTwo">
<h1 id="titleTwo">Output Field 2</h1>
<p id="outputTwo"></p>
</div>
</body>
</html>
CSS:
body {
width: 100%;
margin: 0;
padding: 0;
font-family: Verdana, Geneva, sans-serif;
font-size: 15px;
}
.userField {
display: inline-block;
width: 44%;
margin: 15px;
padding: 15px;
background-color: lightgrey;
border-radius: 13px;
box-shadow: 3px 3px 3px slategrey;
}
#submission {
text-align: center;
}
#divOne {
display: inline-block;
margin: 15px;
padding: 15px;
width: 44%;
word-wrap: break-word;
background-color: lightgrey;
}
#divTwo {
display: inline-block;
background-color: lightgrey;
width: 44%;
word-wrap: break-word;
margin: 15px;
padding: 15px;
}
#titleOne {
background-color: white;
width: 240px;
border-radius: 30px;
padding: 6px;
}
#titleTwo {
background-color: white;
width: 240px;
border-radius: 30px;
padding: 6px;
}
JS:
const fieldOne = document.querySelector("#textAreaOne");
const fieldTwo = document.querySelector("#textAreaTwo");
function compare(){
document.querySelector("#outputOne").innerHTML = "";
document.querySelector("#outputTwo").innerHTML = "";
document.querySelector("#divOne").style.visibility = "hidden";
document.querySelector("#divTwo").style.display = "hidden";
let dataOne = [];
let arrOne = fieldOne.value;
let temp = arrOne.split("");
dataOne.push(temp);
let dataTwo = [];
let arrTwo = fieldTwo.value;
let tempTwo = arrTwo.split("");
dataTwo.push(tempTwo);
if (fieldOne.value.length <= fieldTwo.value.length){
for (var i = 0; i<fieldOne.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
document.querySelector("#outputOne").innerHTML += "<span style='color:green'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:green'>" + dataTwo[0][i] + "</span>";
} else {
document.querySelector("#outputOne").innerHTML += "<span style='color:red'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldOne.value.length < fieldTwo.value.length){document.querySelector("#outputTwo").innerHTML += "<span>...</span>";}
}
else {
for (var i = 0; i<fieldTwo.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
document.querySelector("#outputOne").innerHTML += "<span style='color:green'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:green'>" + dataTwo[0][i] + "</span>";
} else {
document.querySelector("#outputOne").innerHTML += "<span style='color:red'>" + dataOne[0][i] + "</span>";
document.querySelector("#outputTwo").innerHTML += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldTwo.value.length < fieldOne.value.length){ document.querySelector("#outputOne").innerHTML += "<span>...</span>";}
}
document.querySelector("#divOne").style.visibility = "visible";
document.querySelector("#divTwo").style.visibility = "visible";
}
https://codepen.io/Axfinger/pen/QxvbqM?editors=0010
谢谢
您的代码运行缓慢的主要原因是您不断为每个字母修改 innerHtml。
即使有多个段落,这种方法也更快:
[...]
let outOne = '';
let outTwo = '';
if (fieldOne.value.length <= fieldTwo.value.length){
for (var i = 0; i<fieldOne.value.length; i++){
if (dataOne[0][i] === dataTwo[0][i]){
outOne += dataOne[0][i];
outTwo += dataTwo[0][i];
} else {
outOne += "<span style='color:red'>" + dataOne[0][i] + "</span>";
outTwo += "<span style='color:red'>" + dataTwo[0][i] + "</span>";
}
}
if (fieldOne.value.length < fieldTwo.value.length){outTwo += "...";}
}
[...]
outputOne.innerHTML = outOne;
outputTwo.innerHTML = outTwo;
请注意,为了清楚起见,我省略了部分代码。
也就是说,如果您还需要更快的速度:
- 查找以将尽可能多的数据拟合到红色跨度中。那就是不同字母的整个连续子序列。
- 在 webworker 中执行该函数(将花费类似的时间,但至少不会冻结浏览器)。