虽然其他分析者专注于猜测您的愿望(解析 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。最慢的方法是createHTMLDocument
3.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+。