Each time an element of the DOM changes, the browser will have to recalculate elements and styles and also it might have to re-flow the page. The following is the typical workflow:

Recalculate Style → Layout → Paint

  1. Recalculate Style: changing the DOM causes the browser to recalculate element styles and layout.
  2. Layout: step that uses the recalculated style to figure out positions and shapes of objects.
  3. Paint: Elements are shown on the screen.

What is the Chrome rendering tab used for?

The Chrome Rendering Tab can be used to debug rendering issues such as scrolling performance issues, painting issues due to dynamic content and much more. This tab is usually not available by default, but it can be activated by selecting ‘Developer tools’ > ‘More tools’ > ‘Rendering’.

Identifying paint bottlenecks

The first JavaScript example shows how Chrome can highlight areas of the screen that need to be repainted when the DOM changes. For this example to work, the ‘Paint flashing’ checkbox in the ‘Rendering’ tab has to be activated. The reader will need to create a simple HTML file with two DIV sections with the correct IDs:

function getTheTime() {
   setInterval(() => {
      document.getElementById('clock').innerHTML = (new Date).getHours() + ":" + (new Date).getMinutes() + ":" + (new Date).getSeconds();
   }, 1000);
}
const textAppend = document.getElementById('textToAppend');
for(let i = 0; i < 1000; i++) {
   const t = document.createElement('P');
   t.textContent = `Index is ${i}`;
   textAppend.appendChild(t);
}

Identifying when the scrollbar is part of the rendering surface

The second JavaScript example shows how the browser scrollbar is also part of the rendering surface and might need to be repainted too. For this example to work, the ‘Paint flashing’ checkbox in the ‘Rendering’ tab has to be activated. The reader will need to create a simple HTML file with two DIV sections with the correct IDs:

function getTheTime() {
   setInterval(() => {
      document.getElementById('clock').innerHTML = (new Date).getHours() + ":" + (new Date).getMinutes() + ":" + (new Date).getSeconds();
   }, 1000);
}
const flashScroll = document.getElementById('flashScroll');
let c = 0;
const append = function() {
   if(c >= 1000) {
      return clearInterval(append);
   }
   const mytext = document.createElement('P');
   mytext.textContent = new Date().getDate() + '/' + new Date().getMonth() + '/' + new Date().getFullYear();
   flashScroll.appendChild(mytext);
   c++;
   };
setInterval(append, 1000);

Identifying when adding new elements cause a repaint

The third JavaScript example shows how adding one element to the DOM might cause all elements to be repainted, should their positions or properties be modified. For this example to work, the ‘Paint flashing’ checkbox in the ‘Rendering’ tab has to be activated. The reader will need to create a simple HTML file with two DIV sections with the correct IDs:

const flashScroll = document.getElementById('flashScroll');
let c = 0;
const append = function() {
   if(c >= 1000) {
      return clearInterval(append);
   }
   const mytext = document.createElement('P');
   mytext.textContent = new Date().getDate() + '/' + new Date().getMonth() + '/' + new Date().getFullYear();
   flashScroll.appendChild(mytext);
   c++;
}
setInterval(append, 1000);
setTimeout(() => {
   const prependContent = document.createElement('P');
   prependContent.textContent = '###BEGINNING OF THE PAGE###';
   document.body.prepend(prependContent);
}, 3000);

Differences between DOM and canvas

The fourth JavaScript example shows the difference between DOM and canvas. Canvas can repaint just those areas of the screen that change, without affecting the whole page, which might result in better performances. For this example to work, the ‘Paint flashing’ checkbox in the ‘Rendering’ tab has to be activated. Also, in the HTML page, the tag CANVAS is to be used instead of the usual DIV:

function startTime() {
   setInterval(() => {
      document.getElementById('clock').innerHTML = (new Date).getHours() + ":" + (new Date).getMinutes() + ":" + (new Date).getSeconds();
   }, 1000);
}
const myCanvas = document.getElementById('geometry');
const context = myCanvas.getContext('2d');
context.beginPath();
context.arc(100, 75, 50, 0, 2 * Math.PI);
context.fillStyle = 'green';
context.fill();
context.beginPath();
context.arc(150, 75, 50, 0, 2 * Math.PI);
context.fillStyle = 'red';
context.fill();
context.beginPath();
context.arc(200, 75, 50, 0, 2 * Math.PI);
context.fillStyle = 'blue';
context.fill();
setTimeout(() => {
   context.beginPath();
   context.arc(200, 75, 50, 0, 2 * Math.PI);
   context.fillStyle = 'grey';
   context.fill();
}, 3000);
setTimeout(() => {
   context.beginPath();
   context.arc(150, 75, 25, 0, 2 * Math.PI);
   context.fillStyle = 'blue';
   context.fill();
}, 5000);

Although usually canvas performances are great, they might not be the perfect solution for all websites as canvas might require large amount of code to work. Also, canvas might not perform very well when managing large objects. On the other hand, DOM is easily manageable via CSS, redrawing DOM frames is automatically done by the browser. DOM is not designed for complex graphics and animations!

Watch this tutorial on YouTube

YouTubeThumbnail

Previous Post Next Post