2

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???

Dmitry
  • 653
  • 3
  • 14

0 Answers0