robmisio
robmisio

Reputation: 1176

Will hidden / obscured SVG animations still cause browser repaints and or performance issues?

I'm considering putting an SVG spinner animation behind some images I'm loading and then having the image stacked on top of the spinner so that the spinner is obscured when the image is loaded. Planning to apply this to a list view with potentially hundreds of items.

First question is, will the obscured SVG spinner (once its respective image loads) continue to cause the browser to repaint? (that sounds expensive)

If yes, the next question would be, if I hide (display: none) the spinner when the image loads, will the hidden spinner continue to cause repainting?

Any other performance thoughts are very welcome.

FWIW, this is an Electron app, so Chromium (a relatively up to date version) is the only browser we're concerned with.

Upvotes: 1

Views: 512

Answers (1)

Isaac
Isaac

Reputation: 11805

This got me interested... using an example SVG I whipped together this test (excuse how scrummy the code is):

document.onclick = function() {
  output.innerHTML += (mySVG.innerHTML + output.innerHTML).replace(/<circle /g,"<circle style='opacity: 0' ");
  preview.innerHTML += mySVG.innerHTML;
}
<div id="mySVG">
<svg width="30px" height="30px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-dual-ring">
    <circle cx="50" cy="50" fill="none" stroke-linecap="round" r="40" stroke-width="4" stroke="#facd9e" stroke-dasharray="62.83185307179586 62.83185307179586" transform="rotate(115.488 50 50)">
      <animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform>
    </circle>
    <circle cx="50" cy="50" fill="none" stroke-linecap="round" r="35" stroke-width="4" stroke="#389798" stroke-dasharray="54.97787143782138 54.97787143782138" stroke-dashoffset="54.97787143782138" transform="rotate(-115.488 50 50)">
      <animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;-360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform>
    </circle>
  </svg>
</div>
<div id="output"></div>
<div id="preview"></div>

As you can see, when you click lots on the document, all the fully transparent spinning circles start to slow down the browser rendering. Looks like the animations do still trigger.

In this example with display: none; we get the same result, the div#preview is noticeably slower:

document.onclick = function() {
  output.innerHTML += (mySVG.innerHTML + output.innerHTML).replace(/<circle /g,"<circle style='display: none' ");
  preview.innerHTML += mySVG.innerHTML;
}
<div id="mySVG">
<svg width="30px" height="30px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-dual-ring">
    <circle cx="50" cy="50" fill="none" stroke-linecap="round" r="40" stroke-width="4" stroke="#facd9e" stroke-dasharray="62.83185307179586 62.83185307179586" transform="rotate(115.488 50 50)">
      <animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform>
    </circle>
    <circle cx="50" cy="50" fill="none" stroke-linecap="round" r="35" stroke-width="4" stroke="#389798" stroke-dasharray="54.97787143782138 54.97787143782138" stroke-dashoffset="54.97787143782138" transform="rotate(-115.488 50 50)">
      <animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;-360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform>
    </circle>
  </svg>
</div>
<div id="output"></div>
<div id="preview"></div>

Upvotes: 1

Related Questions