如何优化字符串到DOM的转换?

时间:2012-10-07 20:25:13

标签: javascript dom optimization element

当我尝试填充在JavaScript中创建的div时,我遇到了一个轻微的“滞后”:

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

但是,由于HTML代码的范围,这很自然;有时它长度超过300,000个字符,它来自GM_xmlHttpRequest,有时需要1000毫秒(give or take)来完成,再加上由DOM化程引起的额外500毫秒。

我试图使用substr删除大量文本(授予不是我可能想到的最好的想法),并且它在大多数情况下令人惊讶地工作,但在某些时候元素会无法接受HTML代码(可能无法匹配&lt; *。?&gt;)。

我只需要访问存储在里面的极少量文本; regexp是每bobince个问题,并且认为这是最好的方法。

编辑:我倾向于提到我解析DOM的定义被低估了,我的意思是说这个'文本'是我修改的很多元素的textContent。因此,regexp不是一种选择。

3 个答案:

答案 0 :(得分:3)

虽然其他的ansers专注于猜测你的愿望(解析没有字符串操作的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;
}

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

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

bench mark表明原始方法是最快的 4.64 Ops / s ,其次是DOMParser方法 4.22 Ops / s 。最慢的方法是createHTMLDocument方法 3.72 Ops / s 。虽然差异很小,但我绝对推荐DOMParser,原因如前所述。


我知道您正在使用GM_xmlhttprequest来获取数据。但是,如果您能够使用XMLHttpRequest,我建议您尝试使用以下方法:您可以获取a document as a response

而不是将纯文本作为回复。
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的其他域:在域名等于其他域的文档中插入iframe(例如http://example.com/favicon.ico ),并将其用作代理(也为此页面激活GM脚本)。插入iframe的开销很大,因此该选项对于一次性请求是不可行的。

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我有大量的HTML并且需要花费很长时间才能放入DOM而你只需要一小部分内容,这样做的方法更快:

  1. 让您的服务器仅提供您实际需要的HTML部分。这将节省网络传输时间和DOM解析时间。

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