0

当我尝试填充用divJavaScript 创建的时,我遇到了一点不方便的“滞后”:

var el = document.createElement("div");
el.innerHTML = '<insert string-HTML code here>'

但是,由于 HTML 代码的范围,这是很自然的;有时它的长度超过 300,000 个字符,它是从 GM_xmlHttpRequest 派生的,有时需要 1000 毫秒(给或取)才能完成,加上 DOM 化导致的额外 500 毫秒。

我试图摆脱大量的文本使用substr(授予不是我可能想到的最好的想法),它在大多数情况下令人惊讶地工作,但在某些时候元素将无法接受 HTML 代码(可能是无与伦比的<*.?>)。

我只需要访问存储在其中的极少量文本;正则表达式是不可能的,并且认为这将是最好的方法。

编辑:我倾向于提到我对解析 DOM 的定义被低估了,我的意思是说这个“文本”是我修改的很多元素的文本内容。因此,正则表达式不是一种选择。

4

3 回答 3

3

虽然其他分析者专注于猜测您的愿望(解析 DOM 而不进行字符串操作)是否有意义,但我将把这个答案专门用于比较合理的 DOM 解析方法。

为了公平比较,我假设我们需要<body>解析 DOM 的元素(作为根容器)。我在http://jsperf.com/domparser-vs-innerhtml-vs-createhtmldocument创建了一个基准。

var testString = '<body>' + Array(100001).join('<div>x</div>') + '</body>';

function test_innerHTML() {
    var b = document.createElement('body');
    b.innerHTML = testString;
    return b;
}
function test_createHTMLDocument() {
    var d = document.implementation.createHTMLDocument('');
    d.body.innerHTML = testString;
    return d.body;
}
function test_DOMParser() {
    return (new DOMParser).parseFromString(testString, 'text/html').body;
}

第一种方法是您当前的方法。它在所有浏览器中都得到很好的支持。
尽管第二种方法有创建完整文档的开销,但它比第一种方法有很大的好处:加载资源(图像)。与第一个文档的潜在网络流量相比,文档的开销是微不足道的。

最后一种方法在写作时仅在 Firefox 12+ 中受支持(没问题,因为您正在编写 GreaseMonkey 脚本),并且是这项工作的特定工具(具有与前一种方法相同的优点)。顾名思义,它是一个 DOM 解析器。

基准测试显示原始方法最快4.64 Ops/s,其次是 DOMParser 方法4.22 Ops/s。最慢的方法是createHTMLDocument3.72 Ops/s方法。虽然差异很小,所以DOMParser出于前面所述的原因,我绝对推荐。


我知道您正在使用它GM_xmlhttprequest来获取数据。但是,如果您能够XMLHttpRequest改用,我建议尝试以下方法:您可以获取文档作为响应,而不是获取纯文本作为响应

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/');
xhr.responseType = 'document';
xhr.onload = function() {
    var bodyElement = xhr.response.body; // xhr.response is a document object
};
xhr.send();

如果 Greasemonkey 脚本在单个页面上长时间处于活动状态,您仍然可以将此功能用于不支持 CORS 的其他域:在域等于其他域(例如http://example.com/favicon.ico)的文档中插入 iframe,并将其用作代理(也为此页面激活 GM 脚本)。插入 iframe 的开销很大,因此此选项不适用于一次性请求。

对于同源请求,此选项可能是最好的选项(尽管没有进行基准测试,但可以争辩说直接返回文档而不是中间字符串操作会带来性能优势)。与DOMParser+text/html 方法不同,responseType="document"更多浏览器支持:Chrome 18+、Firefox 11+ 和 IE 10+。

于 2012-10-07T21:05:57.343 回答
0

我你有大量的 HTML,并且需要很长时间才能放入 DOM,而你只想要其中的一小部分,加快速度的方法是:

  1. 让您的服务器只提供您真正想要的 HTML 部分。这将节省网络传输时间和 DOM 解析时间。

  2. 如果您无法修改服务器,那么您需要手动解析一些 HTML 以消除您不想要的部分,这样就不会将那么多部分放入 DOM 中。正则表达式是搜索巨型字符串的较慢方法之一,因此.indexOf()如果可能的话,最好使用类似的方法来识别您所定位的一般区域。如果有唯一的 id 或类,并且您知道 HTML 的一般形式,则可以使用更快的算法来识别目标区域。但是,如果您不披露要解析的实际 HTML,我们无法提供比这更多的细节。

于 2012-10-07T20:49:09.380 回答
0

我们需要更多地了解您的应用程序,但是当您处理如此多的 HTML 内容时,您可能只想使用iframe. 它是异步的,不会拖延 JS 代码,也不会引入过多的潜在调试问题。

使用来自 的原始 HTML 填充元素可能很危险xmlhttprequest,主要是由于潜在的 XSS 漏洞和几乎不可能修复的 HTML 故障。如果可能,请考虑使用模板(我相信 JQuery 提供了某种模板解决方案)并加载少量 XML/JSON/等。只有在使用 aniframe是不可能的情况下才这样做。

于 2012-10-07T20:39:06.097 回答