GoogleChromeLabs / css-triggers

A reference for the render impact of mutating CSS properties.
https://csstriggers.com/
Apache License 2.0
899 stars 70 forks source link

Wrong data #21

Open Qwal opened 8 years ago

Qwal commented 8 years ago

Hey, are you sure you have correct data for Webkit and Gecko? For example - is it true that using "transform" in webkit causes layout recalculation?

surma commented 8 years ago

The data is correct in so far as that it reflects what the respective DevTools are showing when running the tests. Engineers from both Webkit and Gecko were just as surprised as we were, but we haven’t heard from them since.

Frizi commented 8 years ago

@surma Looking into that further, transform behaves totally differently when you force to create a render layer. This happens specifically for 3d transforms (translateZ(0) counts). Because it's so different, shouldn't there be a separate entry on the list for that case?

mstange commented 8 years ago

Speaking as a Gecko developer who works on painting, subsequent changes to transform absolutely don't cause painting in Gecko. With two exceptions: If your element is much larger than the viewport, we only paint those areas that are currently inside the viewport, so you'll see some painting as you move other areas into the viewport. The other exception is scaling: If you cross a power-of-two scaling threshold, we re-rasterize the layer contents at a different resolution.

How did you gather the data? If you see painting during transforms in cases where the exceptions I mentioned don't apply, I'd love to hear about those cases.

I'm also interested in knowing through what channel you contacted Gecko engineers.

paullewis commented 8 years ago

The data came from Jordan Santell a while ago (on the old repo over on my personal account). I'm more than happy to take PRs for fixes, though from my POV if we could pull logs directly via WebDriver etc then it would remove the human element entirely. Unfortunately today we can only get the logs for Chrome, but I'd love that to change!

surma commented 8 years ago

@mstange Help would be greatly appreciated to automate this for Gecko!

In case you haven’t seen it: The _suite folder contains the code to generate and run the test suite.

mstange commented 8 years ago

Thanks for the pointers! I'll take a look next week.

mstange commented 8 years ago

Sorry for taking so long here. This is still on my to-do list.

I've run gogo() on suite/html/transform-change.html, and indeed, Firefox does a paint. Apparently there is a Firefox bug here due to the table elements. If I remove the table, gogo() causes no paints, and there is no paint marker in the performance recording. I need to look into it some more.

mstange commented 8 years ago

Oh, I had missed the #targetElement.active * rule. So the test changes the transform property on the table elements themselves, not just on the container div! And yes, Firefox doesn't support cheap transform changes on table elements yet.

It's a little unfortunate that Firefox's lack of efficient transform support on table elements makes it look like it has slow transforms in general. I don't think many people set transforms on table elements.

surma commented 8 years ago

That is very interesting info! And yes, I agree that it is unfortunate that one “edge-case” is distorting the data for Firefox.

I’ll try and come up with a different template that accommodates for this.

paullewis commented 8 years ago

I'm all up for changing the data to suit here, since it's not the common case. In the meantime, while Surma does the change to the template, we can update the data to match expectations.

Thanks for taking time out to look over it :)

paullewis commented 8 years ago

In fact, @Qwal can I ask if you'd mind making a PR that sets the properties to the correct values as you see them? I assume it's the same for opacity as it is for transform? I'd do it myself, but I think it's better to come from you since you know Gecko far better than we do.

Qwal commented 8 years ago

@paullewis I think you wanted to ask @mstange as he's a Gecko developer. I just found it strange in the data, as from my experience CSS animations using transform are smooth both in Chrome & FF.

paullewis commented 8 years ago

@Qwal Sorry, my mistake. Should. Read. More. Closely!

mstange commented 8 years ago

Thanks for your offer to change the template.

I've created a pull request to change the data for transform and opacity. There are some more properties for which we're missing Gecko data, but I don't want to test those manually right now.

zikaari commented 8 years ago

@mstange

..If your element is much larger than the viewport, we only paint those areas that are currently inside the viewp...

webkit seems to behave just like that!

I ran some tests inside the devtools console, and any transformations (I tested scale and translateX) that didn't cause the element to overflow the body, didn't trigger layout.

The first transformation that leads to horizontal scrollbar = layout opertation. subsequent transformations = no layout.

The first transformation that leads to vertical scrollbar = layout opertation. subsequent transformations = no layout.

If body's overflow property is set to overflow: hidden, no layout, no matter what.

Proof

1. Serve this code as html file.

<!DOCTYPE html>
<html>
  <head>
    <title>Browser Rendering</title>
    <style>
      #subject {
        width: 4px;
        height: 4px;
        background: blue;
        opacity: .2;
        transform-origin: top left;
      }
    </style>
  </head>
  <body>
    <div id="subject" style="transform: scale(1) translateX(0)"></div>
  </body>
</html>

2. Fire up Chrome devtools and switch to Timeline view. 3. Make sure the console is open at the same time, by hitting ESC. 4. Start recording and execute this code in the console.

var testSubject = document.querySelector("#subject");
var activeScale = 0, activeXTranslation = 0;

var update = () => {
    testSubject.setAttribute('style', `transform: scale(${ activeScale }) translateX(${ activeXTranslation }%);`);
}

var increaseScaling = (factor) => {
    activeScale += factor;
    update();
}

var increaseTranslation = (factor) => {
    activeXTranslation += factor;
    update();
}

var transformWithinViewport = () => {
    activeScale = 150, activeXTranslation = 70;
    update();
}

var haveItRenderHorizontalScrollBars = () => {
    activeScale = 200, activeXTranslation = 180;
    update();
}

var haveItRenderVerticalScrollBars = () => {
    activeScale = 500, activeXTranslation = 180;
    update();
}

requestAnimationFrame(() => {
     // Applied at frame_1, no layout
    transformWithinViewport();

    requestAnimationFrame(() => {
        // Applied at frame_2, still within viewport so no layout
        increaseScaling(50);

        requestAnimationFrame( () => {
            // Applied at frame_3, still within viewport so no layout
            increaseTranslation(50);

            requestAnimationFrame( () => {
                // Applied at frame_4, beyond viewport, horizontal scrollbars required, layout triggered
                haveItRenderHorizontalScrollBars();

                requestAnimationFrame( () => {
                    // Applied at frame_5, horizonal scrollbars are ready, another layout not triggered
                    increaseTranslation(50);

                    requestAnimationFrame( () => {
                        // Applied at frame_6, vertical scrollbars required, layout triggered
                        haveItRenderVerticalScrollBars();

                        requestAnimationFrame( () => {
                            // Applied at frame_7, vertical scrollbars are ready, another layout not triggered
                            increaseScaling(700); 

                        });                        
                    });
                });
            });
        });
    });
});

Now follow Step 1 to 4, but this time body overflow set to hidden, get amazed!

grundmanise commented 4 years ago

@paullewis Hey, so the actual behaviour for opacity is different from what is stated in this web fundamentals article (if css-triggers got it right).

If you can confirm it is the case, I'd create an issue for the article then.