gpt4 book ai didi

javascript - 在 Javascript 中使用正则表达式解析 XHTML 字符串并将其转换为 DOM

转载 作者:行者123 更新时间:2023-11-30 06:41:13 24 4
gpt4 key购买 nike

免责声明: 在你无法解析 html-with-regex 盲目咒语开始之前 - 请给我怀疑的好处并阅读这个问题到最后( + 假设我已经知道 That RegEx-ing the HTML will drive you crazyParsing Html The Cthulhu Way )


大多数对 Regex 匹配 HTML 的提示来自于 HTML 结构松散,Regex 很难匹配不同的问题和用户错误 + 一些其他的东西,比如递归等。

但是 - 如果 HTML 实际上是有效的 XHTML(或更像 XML),它源自受控环境(不是一般的用户生成的 HTML 文档,而是例如您将在客户端中使用的 HTML 片段模板)侧模板引擎)并且已经手动检查错误并多次验证?


让我解释一下我为什么感兴趣。我正在用 Javascript 对不同的 String2DOM 技术进行速度基准测试,我已经测试了从 innerHTML、outerHTML、insertAdjacentHTML、createRange、DOMParser、doc 等所有内容.write(通过 iFrame)甚至 John Riesigs HTMLtoDOM JS 库。

我很好奇是否有更快的方法。

createElement/appendChild(+setAttribute 和 createTextNode)是在 Javascript 中创建 DOM 元素的最快方式。正则表达式是遍历大字符串的最快方式。难道不能将这两种方法结合起来以创建一种更快的方法来将 DOMString 片段解析为 DOM 吗?

一个示例 HTML 字符串:

<div class="root fragment news">

<div class="whitebg" data-name='Freddie Mercury'>
<div id='myID' class="column c2">
<h1>This is my title</h1>
<p>Vivamus urna <em>sed urna ultricies</em> ac<br/>tempor d </p>
<p>Mauris vel neque sit amet Quisque eget odio</p>
</div>

<div class="nfo hide">Lorem <a href='http://google.com/'>ipsum</a></div>
</div>

</div>

因此理想情况下,代码将返回一个 documentFragment,其中正则表达式解析 XHTML soup 并使用 createElement/appendChild (+setAttribute/createTextNode) 来填充元素。 (一个类似但不完整的例子是 HTML2DOM )

我(和世界其他人)非常非常感兴趣,如果这样的东西可以在 JS 中从 DOMString 生成 DOM 时击败旧的 innerHTML。可以吗?

谁愿意试试自己的知识来制作这样的东西?并在 Stackoverflow 的编年史中占有一席之地? :)


EDIT2: 谁曾盲目否决这个问题 - 至少解释一下您认为这个问题有什么问题?我非常熟悉这个主题,提供了它背后的逻辑,还解释了这个场景的不同之处 + 甚至发布了一些提供类似解决方案的链接。你呢?

最佳答案

首先,所有以性能为导向的问题的答案都是“只是对其进行基准测试”。想写代码就写代码,性能不言而喻。

也就是说,我将尝试根据我对网络浏览器行为的了解来回答您的问题,并可能为您节省一些工时。

不,一个自定义的 Javascript 驱动的 HTML 解析器不能“在从 JS 中的 DOMString 生成 DOM 方面击败优秀的旧 innerHTML”。从理论上讲,它可能能够获得同样好的性能,但这种结果的可能性很小。

之所以如此,是因为Javascript是一种解释型语言。一个理想的 JS 解释器会将 JS 代码优化到其原生等效的浏览器 API 调用序列。因此,在最好的情况下,编写与平台原生代码等效的 JS 代码将获得相同的性能:JS 代码不能优于其原生等效代码,因为在幕后,它仍必须进行原生调用。

手头的任务是创建一个 DOM 树。这是设置 innerHTML 时发生的情况元素的:

JS: Browser, render me some HTML! Here's a Javascript string object.

Browser: parse_html_and_create_dom_objects()

Browser: notify_javascript_of_dom_creation()

现在,如果您使用 Javascript 驱动解析器,会发生以下情况:

JS: scan_string_for_next_token()

JS: Browser, add a DOM element here!

Browser: create_dom_object()

JS: scan_string_for_next_token()

JS: Browser, add a DOM element here!

Browser: create_dom_object()

JS: Browser, append the DOM tree you created to this visible-on-screen DOM tree!

Browser: refresh_page_view_and_notify_js()

在 native 版本中,返回浏览器的 JS 调用序列可以全部一起批处理并在纯预优化的 C 中执行。

我认为您认为在 JS 中进行解析比在浏览器内部进行解析可能更快的原因是因为您发现某些网络浏览器调用了 createElement。重复花费的时间少于设置 innerHTML到一 block 。 这是因为这两个调用执行的工作量不同。当您调用 createElement ,您没有进行字符串处理(没有标记化,没有词法分析)。当您调用 innerHTML = <string> , 你是。那么是否innerHTML比一系列 createElement 更快调用取决于从 JS 中逐个获取元素的累积开销是否超过解析 HTML 字符串的成本。换句话说,你作弊了:你的基准测试没有测量等量的工作,因为调用 createElement 的代码必须事先知道要创建哪些元素。

从 JS 中同时解析 HTML 字符串单独创建元素不太可能比在浏览器中同时进行更快。如果您确实设法编写了优于浏览器内部的 JS 代码,请将其提交给上游浏览器作者:Web 浏览器性能改进对每个人都有帮助,我相信开发人员会欣赏从嵌套解释器中获得卓越性能的讽刺意味比他们在那个口译员之外所能取得的最好成绩还要好。

关于javascript - 在 Javascript 中使用正则表达式解析 XHTML 字符串并将其转换为 DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11147229/

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