当我尝试填充在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不是一种选择。答案 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而你只需要一小部分内容,这样做的方法更快:
让您的服务器仅提供您实际需要的HTML部分。这将节省网络传输时间和DOM解析时间。
如果您无法修改服务器,那么您需要手动解析某些HTML以消除您不想要的部分,因此不会将多少部分放入DOM中。正则表达式是搜索巨型字符串的较慢方式之一,因此如果可能的话,最好使用.indexOf()
之类的东西来识别您所定位的一般区域。如果存在唯一的id或类,并且您知道HTML的一般形式,则可以使用更快的算法来识别目标区域。但是,如果没有公开要解析的实际HTML,我们就无法提供更多细节。