我正在制作一个 Firefox 插件,它将单词与 html 文本中的其他单词附加在一起。这段代码可以工作,但是当迭代一个巨大的字典时,我收到一个无响应的脚本错误。
提高此循环速度的最佳方法是什么?
将字典分割成更小的对象?或者设置timeout function ?
var brands = {"manykeys" : "manyvalues"};
function replaceWord(){
for (var key in brands){
htmlreplace(key, key + " (" + brands[key] + ")");
}
}
function htmlreplace(a, b, element) {
if (!element) element = document.body;
var nodes = element.childNodes;
for (var n=0; n<nodes.length; n++) {
if (nodes[n].nodeType == Node.TEXT_NODE) {
var r = new RegExp(a, 'g');
nodes[n].textContent = nodes[n].textContent.replace(r, b);
} else {
htmlreplace(a, b, nodes[n]);
}
}
}
replaceWord();
最佳答案
需要考虑一些因素。这在很大程度上取决于你可以改变什么或不能改变什么。您可以做的更大的改进之一是使用数组而不是键/值对象。
var brands = [
['manykeys0000','manyvalues0000'],
['manykeys0001','manyvalues0001'],
['manykeys0002','manyvalues0002'],
['manykeys0003','manyvalues0003'],
['manykeys0004', ...
];
function replaceWord(){
var i, n = brands.length;
for (i = 0; i < n; ++i) {
htmlreplace(brands[i][0], brands[i][0] + " (" + brands[i][1] + ")");
}
}
其他一些更改也应该会带来微小的改进:
1.) 将nodes.length
移到循环之外。
2.) 如果合适的话,从 replaceWord()
document.body
var body = document.body;
...
htmlreplace(brands[i][0], brands[i][0] + " (" + brands[i][2] + ")", body);
function htmlreplace(a, b, element) {
var nodes = element.childNodes, len = nodes.length;
for (var n=0; n < len; ++n) {
Chrome 和 Firefox 上的综合快速基准测试使速度提高了 30-40%。
<小时/>其他要测试的编辑:
将 var r = new RegExp(a, 'g');
移至 replaceWord()
,并将其作为第一个参数传递给 htmlreplace()
而不是 a
。
function replaceWord(){
var i, n = brands.length;
for (i = 0; i < n; ++i) {
var r = new RegExp(brands[i][0], 'g');
htmlreplace(r, brands[i].join(' (') + ')', elem);
}
}
<小时/>
如果玩超时this article可能会感兴趣。它使用
window.postMessage();
实现自定义setZeroTimeout()
,但不确定它将如何影响您的案例。
关于Javascript 循环遍历大字典会产生无响应的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22600308/