javascript - 如果我使用 translateX(100%),在繁重的 javascript 函数期间,css 动画将停止

标签 javascript css css-animations css-transitions svelte

步骤

  1. 继续回复: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);
  }
}

最佳答案

我花了一些时间在网络浏览器开发工具中测试你的 repl 的性能时间。我的结论是:

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

  • 主线程
  • 合成线程

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

Typically, the main thread is responsible for:

  • Running your JavaScript.

  • Calculating your HTML elements’ CSS styles.

  • Laying out your page. Painting your elements into one or more bitmaps.

  • Handing these bitmaps over to the compositor thread.

Typically, the compositor thread is responsible for:

  • Drawing bitmaps to the screen via the GPU.

  • Asking the main thread to update bitmaps for visible or soon-to-be-visible parts of the page.

  • Figuring out which parts of the page are visible. Figuring out which parts are soon-to-be-visible when you’re scrolling.

  • Moving parts of the page when you scroll.

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

CSS-based animations, and Web Animations where supported natively, are typically handled on a thread known as the "compositor thread". This is different from the browser's "main thread", where styling, layout, painting, and JavaScript are executed. This means that if the browser is running some expensive tasks on the main thread, these animations can keep going without being interrupted.

Other changes to transforms and opacity can, in many cases, also be handled by the compositor thread.

If any animation triggers paint, layout, or both, the "main thread" will be required to do work. This is true for both CSS- and JavaScript-based animations, and the overhead of layout or paint will likely dwarf any work associated with CSS or JavaScript execution, rendering the question moot.

来源: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. 控制台日志 1
  2. 动画停止
  3. 控制台日志 2
  4. 动画运行

使用像素:

  1. 控制台日志 1
  2. 动画仍在运行
  3. 控制台日志 2
  4. 动画结束

关于javascript - 如果我使用 translateX(100%),在繁重的 javascript 函数期间,css 动画将停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62121872/

相关文章:

css - 在 CSS3 中使用旋转过渡动画关键帧

javascript - 通过 JS 触发的 CSS 动画仅每隔一次点击播放一次

javascript - JavaScript 中的十进制比较失败

javascript - jQuery 追加 css 删除反斜杠

css - 如何在一个 div 背景中制作嵌套颜色?

html - 更改浏览器高度时数据被隐藏

javascript - 为什么这个 css transition 不能制作从一个点到另一个点的平滑动画?

javascript - 如何更新 d3.js 中的气泡图?

PHP - 如果文件加载时间超过 1 分钟,如何显示消息?

javascript - 仅在 Dartium 中调试我的 Dart 编写的客户端 Web 应用程序是否足够?