【问题标题】:During heavy javascript function css animation stops if I use translateX(100%)如果我使用 translateX(100%),在繁重的 javascript 函数期间,css 动画会停止
【发布时间】:2020-09-19 03:25:55
【问题描述】:

步骤

  1. 继续 REPL:https://codesandbox.io/s/css-sidebar-animation-100-transform-wxchf?file=/App.svelte
  2. 点击“切换侧边栏”按钮
  3. 动画流畅,流畅
  4. 取消注释第 28 行
  5. 第 29 行评论
  6. 再次点击按钮
  7. 在调用heavy() 函数时动画停止(在toggleSidebar() 函数中)

问题

我不明白为什么会这样?

如果我将 -200px 更改为 -100% 会发生什么导致动画停止?

我该如何解决这个问题?如果我事先不知道侧边栏宽度怎么办?如果是动态的呢?

代码

.sidebar {
  animation: sidebar-slide-right 3s ease-out;
}

@keyframes sidebar-slide-right {
  0% {
    /* transform: translateX(-100%); */
    transform: translateX(-200px);
  }
  100% {
    transform: translateX(0);
  }
}

【问题讨论】:

    标签: javascript css css-animations css-transitions svelte


    【解决方案1】:

    我花了一些时间在 Web 浏览器开发工具中使用性能时间测试您的 repl。我的结论是:

    在现代网络浏览器中,我们有

    • 主线程
    • 合成器线程

    第二个非常好,因为它通过自己承担一些责任来帮助主线程。

    通常,主线程负责:

    • 运行你的 JavaScript。

    • 计算 HTML 元素的 CSS 样式。

    • 布置您的页面。将您的元素绘制成一个或多个位图。

    • 将这些位图交给合成器线程。

    通常,合成器线程负责:

    • 通过 GPU 将位图绘制到屏幕上。

    • 要求主线程更新页面可见或即将可见部分的位图。

    • 确定页面的哪些部分可见。弄清楚哪个 滚动时很快就会看到部件。

    • 滚动时移动页面的某些部分。

    来源:http://sking7.github.io/articles/572118798.html

    基于 CSS 的动画和原生支持的 Web 动画是 通常在称为“合成器线程”的线程上处理。这 不同于浏览器的“主线程”,其中样式、布局、 绘画和JavaScript被执行。这意味着如果浏览器 在主线程上运行一些昂贵的任务,这些动画 可以继续前进而不会被打断。

    在许多情况下,对变换和不透明度的其他更改也可以 由合成器线程处理。

    如果任何动画触发了绘制、布局或两者,“主线程” 将被要求做工作。这对于 CSS- 和 基于 JavaScript 的动画,以及布局或绘制的开销将 可能会使与 CSS 或 JavaScript 执行相关的任何工作相形见绌, 使问题变得毫无意义。

    来源:https://developers.google.com/web/fundamentals/design-and-ux/animations/animations-and-performance

    所以当我们必须处理动画时,合成器非常好。使用 px 作为度量单位很容易,并且可以由合成器线程完成,但是使用 % 会使我们的浏览器计算动画的每个“步骤”,因此主线程必须帮助我们处理它。通过使用await,您可以阻塞主线程,以便您的浏览器等待重新计算位置。当您使用绝对单位时,合成器线程会执行动画,因此即使您阻塞了主线程,您的动画也会顺利运行。

    将您的代码替换为

      async function toggleSidebar() {
        sidebarVisible = !sidebarVisible;
        console.log("1");
        await sleep(800);
        console.log("2");
        heavy(40);
      }
    

    您可以注意到使用 % 原因:

    动画运行

    1. console.log 1
    2. 动画停止
    3. console.log 2
    4. 动画运行

    使用像素:

    1. console.log 1
    2. 动画仍在播放
    3. console.log 2
    4. 动画结束

    【讨论】:

    • 很好的解释。
    • 感谢您的回答。我该如何解决这个问题?如果我不知道侧边栏的宽度怎么办?如果是动态的呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多