Questions(2): spinner-loading-animation inquiries - Delay and let rotateCount

Hello MDN,

Just finished the spinner-loading-animation interactive learning in cooperative async JS and am wondering why there is a slight delay before the loading animation starts. If I were going to apply this method to a loading page, I’d want the animation to begin as soon as the ↻ was visible.

First, I thought that I’d just keep ↻ invisible until the animation started. I tried adding document.spinner.style.display = "none"; in the if (!startTime) section, but that didn’t do anything. Pretty sure my logic is flawed on the placement. How would I actually do this?

My second thought is to force the animation to initiate instantly to avoid having to hide it, but I have no idea how to do that.

Here’s an example of what I aim to achieve: https://beetles.bleeptrack.de/

  • If you click “Print on Shirt” and then “Design 1”, bleeptrack’s got a very similar loading icon that initiates instantly.
  • …Upon inspection of her code, looks like she uses @keyframes within CSS instead of JS for the animation. Which, as I understand, is the faster option as the browser processes it internally.
  • From MDN during the spinner exercise: " Note : In a real world example, you should probably use CSS animations to run this kind of simple animation. However, this kind of example is very useful to demonstrate requestAnimationFrame() usage, and you’d be more likely to use this kind of technique when doing something more complex such as updating the display of a game on each frame. "

All that being said and even though CSS is recommended for this type of animation, is there a way to force JS to initiate this animation instantly or is the delay simply a case of the time it takes to run the code in the particular environment that animation frame is operating in?

PS. let rotateCount = (timestamp - startTime) / 3; I understand that the / 3 slows the rotation by a factor of 3, but what does timestamp - startTime do? Isn’t startTime 0?

@timandes this is interesting — in my experience, the animation does start instantly.

1 Like

No kidding? Hmm… [Jump to line break to skip my debugging journey.]

I played with the performance on yours vs mine. I had changed the layout and made mine look more like a video game load screen: “Loading…” on bottom-left and ↻ bottom-right. I used flex box to move the objects.

Chrome says mine has an “experience shift” - Occurrence 1: Layout shift, which lasts 1034.5ms and seems to be the delay in animation start. I wonder how I can fix this…

[SOLVED] Went back to my code and found that, within my JS, I had one minor difference vs your JS… I had the spinner.style.transform line nested within the curly brace of the rotation count if conditional! Once I moved the spinner transform line out of that if conditional, this fixed the delay!

I think this means that the the code waited until > 359 degrees to start style.transform.


Still trying to logic this portion of the code though…

function draw (timestamp) {
  if (!startTime) {
    startTime = timestamp;
  }

  rotateCount = (timestamp - startTime) / 3;

I don’t understand the (timestamp - startTime) part, mostly. I tried rotateCount = timestamp / 3; and the animation still runs fine? What does subtracting the startTime do?

Nice one Tim; I’m glad you figured this out

I don’t think it really makes much difference in this example — the animation starts immediately, as does the requestAnimationFrame() call, and it doesn’t really matter what rotation position the spinner starts from. But in a more complex example, where you might not have something running all the time, but it depends on the timestamp, then it is useful to record the start time and use it in this fashion.

Gotcha, thanks for explaining that – makes sense.