javascript - 为什么添加不可见的非交互式覆盖会提高滚动同步的性能?[铬合金]
问题描述
我需要同步两个元素的滚动:一个内容区域和一个“标题”。
但是当我使用该scroll
事件通过 CSS 更改另一个元素的位置时,transform
在用户滚动和标题移动之间存在明显的延迟,这会让人分心,尤其是在 Chrome 上。
但是,与使用相同方法同步滚动位置的其他应用程序相比,他们没有。经过几个小时试图找出原因,我终于找到了:它们有一个覆盖整个滚动区域的不可见覆盖层,这也是非交互式的(CSS pointer-events: none
)
我在下面准备了一个游乐场,覆盖层是可见的,并且没有覆盖整个区域,因此可以轻松进行比较。
至少这种行为发生在我的机器上,一台带有 Chrome 的 Mac,我滚动触控板手势。还需要有一些负载,所以这个片段还每 100 毫秒添加一个 30 毫秒的阻塞循环来模拟一个
const content = document.getElementById("content");
const header = document.getElementById("header");
// Add content
const helloes = new Array(100).fill("Hello!").join("<br /><br />");
header.innerHTML = content.innerHTML = helloes;
// Synchronize scroll of content to header by adding `transform`
content.addEventListener("scroll", (evt) => {
header.style.transform = `translateY(${-content.scrollTop}px)`;
});
// Simulates performance hit, either low-end computer or a component doing extra load
setInterval(() => {
let start = Date.now();
while (Date.now() < start + 30);
}, 120);
.main {
position: relative;
display: flex;
}
.main>div {
overflow: auto;
height: 200px;
padding: 10px;
border: 1px solid black;
border-radius: 5px;
white-space: nowrap;
}
#content {
padding-right: 200px;
}
#overlay {
position: absolute;
left: 160px;
top: 50px;
width: 100px;
height: 100px;
box-sizing: border-box;
background: rgba(0, 0, 0, 0.3);
pointer-events: none;
}
<div class="main">
<div>
<div id="header">
</div>
</div>
<div id="content">
</div>
<div id="overlay"></div>
</div>
由于重现可能非常棘手,因此我在此图像中记录了此行为
这是非常微妙的,但正如你所看到的,当我用鼠标在滚动区域上滚动时,会出现明显的滞后。如果我在非交互式叠加层上滚动,滚动同步是完美的。
但是,我完全不明白为什么会发生这种情况 - 添加叠加层并在其上使用鼠标滚动会提高性能的原因是什么?
解决方案
推荐阅读
- flutter - Flutter 更改验证错误消息位置
- html - 与媒体查询相关的 HTML 和 css
- php - exec() 中的 php 变量
- ios - 如果我没有 iPad,如何在 Mac 上使用 AR 测试 swift-playground?
- typescript - 如何从我在打字稿中创建的类型中获取密钥
- node.js - 使用 superagent 测试经过身份验证的快速端点不起作用?
- html - 有没有一种方法可以在焦点处于焦点时向选择标签添加样式并且还可以查看下拉菜单
- swagger - 如何将 Swagger 与 Nest.js API 和 SPA 之间共享的 DTO 一起使用?
- sql - 按名称分组的连续日期范围内的最小和最大日期
- c++ - CPU如何“投射”浮点x87(我认为)值?