Bug 1524480 Comment 15 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

So it turns out that whether or not Element.animate flushes is observable and it doesn't flush in Chrome but does in Safari TP.

Suppose we have:

```css
div {
  opacity: 0.1;
  width: 100px;
  height: 100px;
  background: black;
  transition: 1s opacity linear;
}
```

And then we do:

```js
// Just to be sure, flush style
getComputedStyle(div).opacity;
```

At this point the computed opacity of `div` is 0.1.

Now, suppose we update the specified opacity to 0.2 but DON'T flush style:

```js
div.style.opacity = '0.2';
```

Then trigger an on the same element:

```js
div.animate({ opacity: [ 0.6, 1] }, 1000);
```

At this point if `Element.animate()` flushes style it will cause us to trigger a transition from 0.1 to 0.2.

However, if Element.animate() does NOT flush style we will:

* Generate a new Animation animating from 0.6 to 1.
* Then on the next restyle we will have a before-change style opacity of 0.6 (since we bring declarative animations up-to-date as part of calculating the before-change style).
* And we we also have an after-change style of 0.6 (for the same reason).

Since the before-change style and after-change style have not changed, no transition will be generated.

Test case: https://codepen.io/birtles/pen/YBxxBd

Given that this is observable we should spec what the behavior is. I think we should definitely NOT flushing since requiring a flush would mean that Element.animate() both flushes AND dirties style. As a result, if the author generates a number of animations in a single animation frame, the browser would be required to flush multiple times per frame.

It's probably no coincidence that the Greensock test case[1] is much more performance in Chrome (doesn't flush) than in Firefox and Safari.

[1] https://greensock.com/js/speed.html
So it turns out that whether or not Element.animate flushes is observable and it doesn't flush in Chrome but does in Safari TP.

Suppose we have:

```css
div {
  opacity: 0.1;
  width: 100px;
  height: 100px;
  background: black;
  transition: 1s opacity linear;
}
```

And then we do:

```js
// Just to be sure, flush style
getComputedStyle(div).opacity;
```

At this point the computed opacity of `div` is 0.1.

Now, suppose we update the specified opacity to 0.2 but DON'T flush style:

```js
div.style.opacity = '0.2';
```

Then trigger an animation on the same element:

```js
div.animate({ opacity: [0.6, 1] }, 1000);
```

At this point if `Element.animate()` flushes style it will cause us to trigger a transition from 0.1 to 0.2.

However, if Element.animate() does NOT flush style we will:

* Generate a new Animation animating from 0.6 to 1.
* Then on the next restyle we will have a before-change style opacity of 0.6 (since we bring declarative animations up-to-date as part of calculating the before-change style).
* And we we also have an after-change style of 0.6 (for the same reason).

Since the before-change style and after-change style have not changed, no transition will be generated.

Test case: https://codepen.io/birtles/pen/YBxxBd

Given that this is observable we should spec what the behavior is. I think we should definitely NOT flushing since requiring a flush would mean that Element.animate() both flushes AND dirties style. As a result, if the author generates a number of animations in a single animation frame, the browser would be required to flush multiple times per frame.

It's probably no coincidence that the Greensock test case[1] is much more performance in Chrome (doesn't flush) than in Firefox and Safari.

[1] https://greensock.com/js/speed.html
So it turns out that whether or not Element.animate flushes is observable and it doesn't flush in Chrome but does in Safari TP.

Suppose we have:

```css
div {
  opacity: 0.1;
  width: 100px;
  height: 100px;
  background: black;
  transition: 1s opacity linear;
}
```

And then we do:

```js
// Just to be sure, flush style
getComputedStyle(div).opacity;
```

At this point the computed opacity of `div` is 0.1.

Now, suppose we update the specified opacity to 0.2 but DON'T flush style:

```js
div.style.opacity = '0.2';
```

Then trigger an animation on the same element:

```js
div.animate({ opacity: [0.6, 1] }, 1000);
```

At this point if `Element.animate()` flushes style it will cause us to trigger a transition from 0.1 to 0.2.

However, if Element.animate() does NOT flush style we will:

* Generate a new Animation animating from 0.6 to 1.
* Then on the next restyle we will have a before-change style opacity of 0.6 (since we bring declarative animations up-to-date as part of calculating the before-change style).
* And we we also have an after-change style of 0.6 (for the same reason).

Since the before-change style and after-change style have not changed, no transition will be generated.

Test case: https://codepen.io/birtles/pen/YBxxBd

Given that this is observable we should spec what the behavior is. I think we should definitely NOT flushing since requiring a flush would mean that Element.animate() both flushes AND dirties style. As a result, if the author generates a number of animations in a single animation frame, the browser would be required to flush multiple times per frame.

It's probably no coincidence that the Greensock test case[1] is much more performance in Chrome (doesn't flush) than in Firefox and Safari (do flush).

[1] https://greensock.com/js/speed.html

Back to Bug 1524480 Comment 15