Please, take a look at this fiddle (I am using Vue.js to generate lots of DOM nodes here, but my question doesn't seem to be a Vue related issue): https://jsfiddle.net/dmaevsky/kswj23r1/117/ .
When I am monitoring performance using Chrome's performance tool while pressing the button in a rapid succession, I am seeing 42ms 'Update Layer Tree' rendering delay, which makes sense, since the stuff is moving on page, so why not (I am still wondering btw whether there's a way to eliminate this).
However, things get awry when I uncomment the line 30, thus manually setting the td's styles in Javascript:
//nr = 50, nc = 50;
for (let i = 0; i < nr; i++) {
for (let j = 0; j < nc; j++) {
this.$refs[i + ':' + j][0].style.color = 'blue';
}
}
When I now monitor the performance I see all 2500 TD nodes added to the "Recalculating styles" in Chrome when 'Shift down' button is pressed. I just cannot see why that would make any sense ? Using a class instead of setting styles manually does not cause this to happen.
This is just an attempt to understand the browser's style invalidation logic, not a real application, so the number of DOM nodes here is intentionally kept higher than one would reasonably need in a real world application, though close enough.
UPDATE: This actually DOES seem to be a Vue.js issue finally. I have re-written the code in pure JS (complete HTML below), and I do not observe the same effect anymore.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Create table test</title>
<style>
body {
font-family: Helvetica;
}
#app {
background: #fff;
padding: 20px;
}
#app {
position: relative;
}
#pane {
position: absolute;
}
.table {
table-layout: fixed;
border-collapse: collapse;
margin: 0;
padding: 0;
border: hidden;
width: 8000px;
height: 1600px;
}
.cell {
width: 100px;
height: 20px;
line-height: 16px;
box-sizing: border-box;
padding: 2px;
background: white;
overflow: hidden;
}
</style>
</head>
<body>
<noscript>
<strong>Need JS</strong>
</noscript>
<button onclick="shift()">Shift down</button>
<div id="app">
<div id="pane"></div>
</div>
</body>
</html>
<script>
var pos = 0;
function shift() {
pos++;
document.getElementById('pane').style.top = pos + 'px';
}
function createTable(nr, nc) {
let table = document.createElement('table');
table.className = 'table';
for (let i = 0; i < nr; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < nc; j++) {
let td = document.createElement('td');
let span = document.createElement('span');
span.innerHTML = i + j;
td.className = 'cell';
td.style.color = 'blue';
td.appendChild(span);
tr.appendChild(td);
}
table.appendChild(tr);
}
return table;
}
document.getElementById('pane').appendChild(createTable(80, 80));
</script>
Question to Vue.js experts then: what does Vue do to DOM to warrant the observed behavior in the first fiddle???