gpt4 book ai didi

javascript - 如何加快向DOM中添加大量复杂HTML的速度

转载 作者:行者123 更新时间:2023-11-30 07:52:35 26 4
gpt4 key购买 nike

我有一个简单的网页,该网页通过AJAX调用加载了大部分内容,该调用返回了大量复杂的HTML。当我将检索到的HTML放入DOM时,它会使浏览器瘫痪相当长的一段时间(Chrome中为5秒,Edge中为35秒)。

我如何将HTML附加到DOM的示例:

$.ajax("example.php").done(function (response) {
const contentElement = document.getElementById('results');
contentElement.innerHTML = response;
});


由于应用程序的复杂性,我想避免不惜一切代价返回JSON并将其转换为HTML。

奇怪的是,在插入的HTML已经可见之后,浏览器会瘫痪一会儿。请参见下面的时间轴,在大约5秒钟的Parse HTML事件发生之前,我可以在屏幕上看到HTML(具有正确的样式)。

Timeline performance

如何加快将HTML解析和附加到DOM的速度?

编辑:我尝试了多种浏览器和多种注入HTML的方法(documentFragments,innerHTML,jquery .html(),append())。所有方法都差不多慢。

Edit2:可以在以下要点中看到注入的确切HTML: https://gist.github.com/Rhinni/3032e74bab0de8f40e08a3392c0243b1

最佳答案

第1部分-这不是代码的加载方式,只是代码无效,即使在页面上进行了硬编码也无法正常工作。




  “奇怪的是,在已经看到插入的HTML之后,浏览器就会崩溃一小会儿。请参见下面的时间轴,在此之前,我可以在大约5秒钟的Parse HTML事件发生之前在屏幕上看到HTML(具有正确的样式)。 ”。



关于HTML的实用性(其荒谬可言),其有效性(并非如此)和功能性(其并非而且可能从未拥有),应该解决一些问题。

您应该validate your HTML因为它是非常无效的,但是在进入这一阶段之前,当您决定验证该混乱时,您需要将其分成大约16个部分,因为大多数在线服务会在很短的时间内摔倒或缩短验证过程。一次要处理这么多。

以下是由于错字而并非孤立问题的问题列表。这些问题会重复多次。我最担心的是值和大多数变量似乎是手工定制的。希望我弄错了,您没有花几个小时来定制会阻碍而不是真正有用的值。


1. #IDs must be unique-在任何情况下,同一页面上均不得重复## cc。



14 ID-固定,14 #accordion-固定,7 #headingOne,7 #model,7 #type,...

还有更多受骗的#brand,我将#ID更改为#accordion 1到14,因为有必要使每个#acordion起作用,而不仅仅是第一个。与#accordion有直接关系的所有相关属性也需要更改,为了功能起见,我设法更改了#accordion。因此,有15个可操作的手风琴,我添加了带有适当设计的手风琴的主页选项卡,如果您决定重新设计其他14个手风琴,则可以将其用作模板。


2.为了使用Bootstrap组件,请根据文档进行制作。


OP代码几乎没有任何制表符,如果您引用Bootstrap documents或什至W3School's short tutorials,您就会知道每个选项卡都必须有一个toggle-parent="#accodion,因此代码很短16 <a>的数量可切换16个标签。这就是为什么您的页面仅显示16个选项卡的第一个选项卡,而不是因为浏览器中途失败而导致的。


3.我注意到的另一个无效之处是,属性<a>(和readonly在较小程度上)被应用于几乎每个表单控件。

 
为什么在required标记上需要readonly属性?在为元素分配属性时,不要开始向所有内容添加大量属性。混乱使可读性,维护和调试变得不可能。



4.有2个柱塞:




Plunk 1是OP(原始帖子)问题的解决方案,此答案的第2部分对此进行了详细说明。 HTML已部分修复,我没有足够的时间修复所有内容。
它有16个标签和15个手风琴起作用。
加载时间从34秒减少到2秒。与边缘。似乎Edge英勇地试图理解已解析的HTML,然后失败了。像Firefox和Chrome这样的真正的浏览器只是将其转储并保留在那里。
Plunk 2是OP代码中的HTML,我的解决方案正在加载它。
结果是一样的,OP代码失败是由于代码本身,而不是因为加载问题。




第2部分-一种将庞大的字符串解析为HTML的稳定方法。如果OP代码确实有效,则不需要。


尝试通过<select>向DOM添加大量标记时,OP遇到严重的延迟。最多需要34秒才能使用Edge完全渲染它,而其他浏览器OP则报告3秒。

我在Edge上的加载时间降低到了2到3秒,而在真正的浏览器(Chrome和Firefox)上立即得到了加载。

尽管OP已经尝试使用createDocumentFragment(),但我认为这是快速加载和解析所述HTML的关键。 OP可能未使用的其他关键组件是:
insertAdjacentHTML()Immediately Invoked Function Expression

使用innerHTML方法而不是insertAdjacentHTML()属性。 innerHTMLinsertAdjacentHTML()的功能强大且用途广泛的版本。

相似之处:


两者都将采用给定的字符串并将其解析为HTML。
两者都很快。


差异:

innerHTML将HTML插入DOM,它不会覆盖DOM中的元素或任何地方的任何现有HTML。 insertAdjacentHTML()覆盖元素的内部。

通过引用innerHTML指向要接收字符串的元素,并使用给定的字符串覆盖该元素的所有内容。如果innerHTML仅指向没有字符串的元素,则它将与该元素的HTML内容一起返回。 innerHTML不能获取的唯一能力是innerHTML的能力。相反,insertAdjacentHTML() SET的功能十分强大,如下所述:insertAdjacentHTML()不仅通过引用元素来定向,还通过其第一个参数(即4个DOMString中的一个)准确告诉相对于引用元素的位置与职位相关:

“ beforebegin”将字符串放在元素开头之前。

      `$elector.before(str)`★


“ afterend”将字符串放在元素末尾之后。

      `$elector.after(str)`★


“ afterbegin”将字符串在紧接后放在元素中。换句话说,字符串被插入到元素的内容之前。

     `$elector.prepend(str)`★


“ beforeend”将字符串放在元素中,紧接在结尾之后。基本上,字符串放置在元素的内容之后。此位置是速度最优化的位置,因为没有前进的兄弟姐妹可以减慢速度。

     `$elector.append(str)`★


insertAdjacentHTML()第二个参数是将被解析为HTML的字符串。使用 Template Literals代替文字字符串使我们更容易进行字符串操作。

    `element.insertAdjacentHTML("beforeend", <input id="${ID+i}" type="${typeArr[i]}" value="${Math.floor(Math.random() * i}">)`


立即调用函数表达式是具有特殊模式的函数。


通常是两个匿名函数:
外部函数包装在括号中。
内部函数通常形成 closure
评估时会创建匿名/表达式函数,然后由于多余的括号将它们立即调用。
它们没有名称,内部函数使用的变量只能由外部函数访问,因为它们是局部作用域。


这些条件使IIFE成为一回事。 IIFE的签名在签名方面略有不同,但是其中一个要点如下:

`(function() { var x = function() {...} x})();`


DOM操作是处理器密集型的,越避免越好。制作 insertAdjacentHTML()是为了让我们能够完成涉及DOM的所有繁琐而繁琐的任务-脱离DOM。我们可以向DocumentFragment及其后代添加尽可能多的元素,文本,属性,设置事件处理程序等,而无需接触DOM。完成所有操作后,只需执行一项DOM操作:

 `document.body.appendChild(frag);` 


演示-如果您想测试实际的演示,请查看此 Plunk



<!DOCTYPE html>
<html>

<head>
<meta charset='utf-8'>
<title>Monstrosity</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</head>

<body>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
(function() {
const str = `Huge Disaster of HTML`
const frag = document.createDocumentFragment();
const node = document.createElement('div');
let build = function(node, str, frag) {
node.insertAdjacentHTML('beforeend', str);
frag.appendChild(node);
document.body.appendChild(frag);
}
build(node, str, frag);
}());
</script>
</body>

</html>

关于javascript - 如何加快向DOM中添加大量复杂HTML的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49496716/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com