CSS animation crashes during JavaScript execution

Question:

I am developing a loading page that will be displayed while the content of the page itself is rendered. It is a simple text that blinks, while circles move from left to right.

The problem is that during times when JavaScript is rendering intensively, the animation hangs and freezes. A colleague told me that it could be a problem when changing the position and size of the elements with CSS (because the flickering does seem to work without problems).

How can I avoid this behavior? What could you do to keep the animation smooth instead of skipping?

This is the code with a force load to show the crash:

// código para crear bloqueo al generar alta intensidad de JS
setInterval(function() {
  for (let j = 0; j < 10000; j++) {
    let o = new Array(20000);
  }
}, 1500);
@keyframes csLoadingBlink {
  0%, 80% {
    opacity: 1;
  }
  40% {
    opacity: 0;
  }
}

@keyframes csLoadingMoveButton {
  0% {
    top: 0;
    width: 2rem;
    height: 2rem;
    left: 0;
  }
  100% {
    top: 1rem;
    width: 0rem;
    height: 0rem;
    left: 100%;
  }
}


.cs-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.cs-brand {
  white-space: nowrap;
  animation: csLoadingBlink 3s linear infinite;
}

.cs-brand span {
  white-space: nowrap;
  display: inline-block;
  color: #000369;
  vertical-align: middle;
}

.cs-name {
  border-right: 1px solid;
  padding-right: 1rem;
  margin-right: 1rem;
  font-size: 2.5rem;
  line-height: 3rem;
}

.cs-name sup {
  font-size: 0.75rem;
}

.cs-slogan {
  font-family: Arial, sans-serif;
  font-size: 1.5rem;
}

.cs-animation {
  width: 100%;
  height: 2rem;
  margin-top: 1rem;
  position: relative;
}

.cs-animation span,
.cs-animation::before {
  display: block;
  content: "";
  position: absolute;
  line-height: 2rem;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: #000369;
}


.cs-animation span {
  animation: csLoadingMoveButton 3s linear infinite;
  animation-fill-mode: backwards;
}

.cs-animation span:nth-of-type(1) {
  animation-delay: 0s;
}

.cs-animation span:nth-of-type(2) {
  animation-delay: 1s;
}

.cs-animation span:nth-of-type(3) {
  animation-delay: 2s;
}
<div class="cs-loading">
  <div class="cs-brand">
    <span class="cs-name">Compa&ntilde;&iacute;a</span>
    <span>Mejor Slogan del Mundo</span>
  </div>
  <div class="cs-animation">
    <span></span>
    <span></span>
    <span></span>
  </div>
</div>

Answer:

Using a worker it seems that it does not lock

(inline example taken from https://stackoverflow.com/a/6454685/1423096 )

the if ( 5 > Math.floor(Math.random() * 100) ) { is so that the console.log does not affect the render.

// código para crear bloqueo al generar alta intensidad de JS
/*
setInterval(function() {
  for (let j = 0; j < 10000; j++) {
    let o = new Array(20000);
  }
}, 1500);
//*/

var blob = new Blob([document.querySelector('#worker1').textContent], {
  type: "text/javascript"
})

// Note: window.webkitURL.createObjectURL() in Chrome 10+.
var worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = function(e) {
  console.log("Received: " + e.data);
}
worker.postMessage("hello"); // Start the worker.
@keyframes csLoadingBlink {
  0%,
  80% {
    opacity: 1;
  }
  40% {
    opacity: 0;
  }
}

@keyframes csLoadingMoveButton {
  0% {
    top: 0;
    width: 2rem;
    height: 2rem;
    left: 0;
  }
  100% {
    top: 1rem;
    width: 0rem;
    height: 0rem;
    left: 100%;
  }
}

.cs-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.cs-brand {
  white-space: nowrap;
  animation: csLoadingBlink 3s linear infinite;
}

.cs-brand span {
  white-space: nowrap;
  display: inline-block;
  color: #000369;
  vertical-align: middle;
}

.cs-name {
  border-right: 1px solid;
  padding-right: 1rem;
  margin-right: 1rem;
  font-size: 2.5rem;
  line-height: 3rem;
}

.cs-name sup {
  font-size: 0.75rem;
}

.cs-slogan {
  font-family: Arial, sans-serif;
  font-size: 1.5rem;
}

.cs-animation {
  width: 100%;
  height: 2rem;
  margin-top: 1rem;
  position: relative;
}

.cs-animation span,
.cs-animation::before {
  display: block;
  content: "";
  position: absolute;
  line-height: 2rem;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: #000369;
}

.cs-animation span {
  animation: csLoadingMoveButton 3s linear infinite;
  animation-fill-mode: backwards;
}

.cs-animation span:nth-of-type(1) {
  animation-delay: 0s;
}

.cs-animation span:nth-of-type(2) {
  animation-delay: 1s;
}

.cs-animation span:nth-of-type(3) {
  animation-delay: 2s;
}
<div class="cs-loading">
  <div class="cs-brand">
    <span class="cs-name">Compa&ntilde;&iacute;a</span>
    <span>Mejor Slogan del Mundo</span>
  </div>
  <div class="cs-animation">
    <span></span>
    <span></span>
    <span></span>
  </div>
</div>

<script id="worker1" type="javascript/worker">
  self.onmessage = function(e) {
    self.postMessage('msg from worker');
  };
  setInterval(
    function() {
      if ( 5 > Math.floor(Math.random() * 100) ) {
        self.postMessage('setinterval still alive');
      }
      for (let j = 0; j <
        10000; j++) {
        let o = new Array(20000);
      }
    }, 1500);
</script>
Scroll to Top