滚动到底部(和强制回流性能问题)
Posted
技术标签:
【中文标题】滚动到底部(和强制回流性能问题)【英文标题】:Scroll to bottom (and forced reflow performance issues) 【发布时间】:2021-08-29 05:10:19 【问题描述】:在收到消息(WebSocket,不重要)后,我正在尝试使用 vanilla JS 滚动到 div
的底部(在我的可滚动网页内)。该消息在div
中添加了一个新元素el
,我希望div
滚动到el
:
div.append(el); // or ...array
// clear div if too many messages here,
// using while (childNodes.length > ...) firstChild.remove();
div.scroll...(el);
使用div.scrollTo(0, div.scrollHeight)
(编辑:或div.scrollTop = div.scrollHeight
)会很好,如果它不是那么慢的话 - 我经常收到很多消息,而且每当我必须用@强制重排时它基本上会冻结浏览器987654329@.
使用el.scrollIntoView()
(编辑:或其变体)实际上要快得多(从简短的未受过教育的分析会话中累积,scrollTo
的 20 秒和scrollIntoView
的 0.6 秒,给定相对相同的负载),但是,我的 @987654333 @ 恰好位于可滚动页面内,scrollIntoView
使整个页面滚动以使 el
出现在视图中。基本上,我希望它滚动到div
的底部,甚至在屏幕外(或达到类似的效果)。
对于这个问题还有其他解决方案吗,或者是否可以修复前两个变体之一?
更新:
使用div.scrollTo(0, Number.MAX_SAFE_INTEGER);
和类似功能仅适用于 Chrome,不适用于 Firefox。虽然运行速度很快(与第二个解决方案相比)。类似的变体 div.scrollTop = Number.MAX_SAFE_INTEGER
实际上由于某种原因表现很差。
【问题讨论】:
【参考方案1】:div.scrollIntoView(false);
这会将您带到 div 的底部。
【讨论】:
抱歉,将div
滚动到视图中不是我想要的。
如果您的意思是el.scrollIntoView(false)
(问题中的el
表示添加到可滚动div
的消息),添加false
(表示alignToTop
参数)不会解决问题中提出的问题。【参考方案2】:
试试div.scrollTop = div.scrollHeight
:
var contents = document.querySelector('.contents');
const before = new Date().getTime();
contents.scrollTop = contents.scrollHeight;
const after = new Date().getTime();
const diff = after - before;
console.log(`Took $diff milliseconds`);
.contents
height:200px;
overflow-y:auto;
.section
height:197px;
border:1px solid;
<div class="contents">
<div class="section">1</div>
<div class="section">2</div>
<div class="section">3</div>
</div>
【讨论】:
使用相同/相似的消息运行分析 10 秒,使用 scrollHeight(您的方法使用 =)运行 2301 毫秒,使用 scrollIntoView 运行 24 毫秒。使用 Chrome,查看线路附近的 Sources 中的时间。强制回流是一件大事。以上是关于滚动到底部(和强制回流性能问题)的主要内容,如果未能解决你的问题,请参考以下文章