javascript - 如果我使用 translateX(100%),在繁重的 javascript 函数期间,css 动画会停止
问题描述
脚步
- 继续 REPL:https ://codesandbox.io/s/css-sidebar-animation-100-transform-wxchf?file=/App.svelte
- 单击“切换侧边栏”按钮
- 动画流畅,流畅
- 取消注释第 28 行
- 评论第 29 行
- 再次点击按钮
- 调用函数时动画停止
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);
}
}
解决方案
我花了一些时间在 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
- 动画停止
- 控制台日志 2
- 动画运行
使用像素:
- 控制台日志 1
- 动画仍在运行
- 控制台日志 2
- 动画结束
推荐阅读
- linux - 可以在适用于 Linux 和 Windows 的 Makefile 中创建符号链接吗?
- .net - 在 Visual Studio 中更改目标框架
- javascript - 如何将文本框和数据表值从视图发送到控制器?
- outlook - 如何使用 Microsoft 图形 API 跨邮箱获取电子邮件的唯一消息 ID?
- algorithm - 函数按预期执行,但在循环结束时返回 nil 值
- sql - 如何使用“选择 * table where * = ?” 在 Swift 中使用 Sqlite3
- python - 如何在变量的最重要数据上创建 python 箱线图
- java - 如何找到哈希图中的最小值?
- python - 在树莓派上测试简单音频的语法错误
- reactjs - 带有 wrapPageElement 的空查询结果