javascript - Google Chrome 中的 DOM 过载问题
问题描述
在 Google Chrome 中使用大量隐藏项目时,我遇到了一些问题。
最近,我发布了一个许多人认为晦涩难懂的问题,很快就关闭了。我找到了这个问题的原因,但到目前为止我不知道如何解决它。
有时在开发页面时,会使用一种方法,即预先创建并隐藏某些元素,然后在必要时显示。
所以这类元素的数量极大地影响了浏览器的响应速度。假设我们有以下代码:
var elem = document.getElementsByClassName ('Founder') [0];
var parent = document.getElementsByClassName ('Cloud') [0];
var empty = document.getElementsByClassName ('empty') [0];
for (var i = 0; i <50000; i ++) {
var clone = elem.cloneNode (true);
// var clone = empty.cloneNode (true);
clone.style.display = 'none';
parent.appendChild (clone);
}
<div class = 'Cloud'>
<input class = 'Founder' type = 'text'>
<div class = 'empty'> </div>
</div>
因此,当我在 Firefox(67.0(64 位))中启动它时,就没有特殊的刹车了。但是当我在 Chrome 版本 74.0.3729.169(官方版本)(64 位)中运行它时,我得到了强大的刹车。
在配置文件中,这可以看作是空任务(系统)。看截图。(来自老主题,一共有64万个节点,但这并没有改变本质)。
有没有办法加快工作,我可以冻结未显示的项目吗?据我了解这些空任务,这是浏览器索引元素或类似内容的时间。
也许有任何设置可以通过编程方式更改,这将加快工作速度(可能需要更多 RAM)。
解决方案
parent.appendChild(...);
是缓慢的一步。您正在向文档中添加 50,000 个节点,即使是隐藏的(应该避免回流布局步骤),它们也将是一大块需要添加的工作。
将它们添加到 aDocumentFragment
会有所帮助,但如果您想快速渲染 640,000 个节点,则效果不大。
提前创建元素然后显示它们可能是避免用户交互卡顿的有用方法,但大型文档通常速度较慢,并且难以快速制作大量节点。
我认为你有两个选择:
将更改分批成更小的工作,并用于
requestAnimationFrame
等待下一帧进行下一批。当浏览器在所有新的 DOM 上工作时,这种方式将停止 jank 和明显的秒左右,但总体上会花费更多时间。或者,当其他工作没有发生时,您可以使用requestIdleCallback
在后台构建大量文档。使用其中任何一个,您都可能会遇到文档显示为交互式但隐藏的 DOM 节点尚不可用的问题,因此您必须对其进行管理。根据需要切换到添加 DOM,而只优化该 DOM。创建一些其他对象来管理您的所有数据(您甚至可以使用 a
Worker
或Comlink将所有数据保留在主 JS 线程之外)。这通常会更快,并且是大多数应用程序所做的,但是您将有更多的工作来优化性能以响应用户操作(他们可能会等待 8 秒让您的应用程序最初加载,但是如果他们点击了他们会期待的东西在 100 毫秒左右的时间内)。
推荐阅读
- python - 检索熊猫数据框中属性的对应行
- java - 以编程方式创建包含 ConstraintLayout 的多个 LinearLayout?
- php - 如何使用 PHP 获取整个 MongoDB 集合
- typescript - 如何让 TypeScript 语言服务不抱怨全局类型?
- scala - 重新格式化 scala 代码和 if/else 语句
- javascript - 在表单中选择复选框时,Ajax 调用不起作用
- django - FileField 的表单无效
- jquery - 使用多个自定义切换按钮过滤数据表
- tensorflow - 将矩阵的每一行与张量流中的另一个矩阵相乘
- ruby-on-rails - 如何使用带有大写列名的 Rails?