为什么主线程会阻止CSS转换动画?

tru*_*ktr 7 javascript css css-transitions css-transforms css-animations

我举了一个例子,对CSS转换进行动画处理,然后单击它,动画被1秒长的循环阻塞。怎么来的?我认为动画转换发生在单独的线程上。

这是示例(单击它以阻塞主线程并因此暂停动画):

window.addEventListener('click', kill)

function kill() {
  var start = +new Date;
  while (+new Date - start < 2000){}
}
Run Code Online (Sandbox Code Playgroud)
    html, body, div {
        width: 100%; height: 100%;
        margin: 0; padding: 0;
        /* background: #364659; */
        /* background: #293442; */
        background: #1E2630;
    }

    @keyframes ShimmerEffect {
        0% { transform: translate3d(-15%, -15%, 0) }
        100% { transform: translate3d(-60%, -60%, 0) }
    }
    .shimmerSurface {
/*         overflow: hidden; */
/*         perspective: 100000px */
    }
    .shimmerSurfaceContent {
        transform-style: preserve-3d;
        background: linear-gradient(
            -45deg,
            rgba(0,0,0,0) 40%,
            rgba(244,196,48,0.6) 50%,
            rgba(0,0,0,0) 60%
        );
        background-repeat: repeat;
        background-size: 100% 100%;
        width: 400%; height: 400%;

        animation: ShimmerEffect 1.8s cubic-bezier(0.75, 0.000, 0.25, 1.000) infinite;
    }
Run Code Online (Sandbox Code Playgroud)
<div class="shimmerSurface">
    <div class="shimmerSurfaceContent"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

codepen链接

编辑:似乎它并未在Safari中被阻止(尽管它会切断渐变),但仅在Chrome和Firefox中被阻止。我们如何在Chrome和Firefox中取消屏蔽动画?

Rob*_*ffe 3

浏览器线程

每个浏览器至少有3个线程;具体运行的内容取决于浏览器。现代浏览器现在都拥有三个以上的线程,但它们仍然具有始终独立的三类线程。为什么?其中一个始终是完全独立的,只能由浏览器访问来处理诸如滚动、打开新选项卡等之类的事情……至少一个将始终用于计算和解析之类的事情,因此将在 CPU 上运行。并且至少有一个线程将在 GPU 上运行,因为屏幕上显示某些内容需要它。

层数

为了让 GPU 知道屏幕上显示的内容,它需要以位图格式光栅化布局。但当物体在屏幕上移动时,最好向 GPU 发送一些可以移动的位图。我们称这些层为层。

正如 @irdkwmnsb 所指出的,我们可以使用layers开发人员工具中的选项卡来准确查看哪些元素已被拆分为单独的位图。

在此输入图像描述

显式创建图层

对于我们知道要转换的任何 HTML 或 SVG 元素,我们可以添加以下 CSS 规则,以确保该元素被分隔到单独的位图层中,并且转换不应被主线程上的其他活动阻止:
will-change: transform

所以添加CSS规则

.shimmerSurfaceContent {
   will-change: transform;
}
Run Code Online (Sandbox Code Playgroud)

应该阻止第一个示例中的转换被阻止。

为什么只在某些浏览器中有效?

某些浏览器可能不会自动将此元素拆分为单独的图层的原因是,创建太多位图图层会带来性能问题,因此它们会小心不要创建太多。另外,当创建为单独的位图并四处移动时,有些东西看起来不太好,因此浏览器可能会避免它。

但对于这个例子来说,我们可以从该图像的两个位图图层中看到,顶部的位图图层具有半透明边缘。类似的事情以前曾在 GPU 计算各种黄色阴影时导致出现锯齿问题。
在此输入图像描述 这可能是 Chrome 之前避免将其分离到新位图图层的原因。