使用 JS 有效地更新页面元素



我正在制作一个游戏并使用数百行

document.getElementById("ID").innerHTML = someVariable;

更新我用函数计算的所有内容。我怎样才能让它变得更好,或者这是最好的方法?我真的不能像这样使用循环

for (var i = 0; i < IDs.length; i++) { document.getElementById("IDs[i]").innerHTML = Variables[i]; }

因为我有这么多不同的变量和不同的 ID。

那么我应该将所有内容重新加工成数组并使用它们还是什么?

感谢您的任何建议!

几件事可以稍微提高性能。不幸的是,jsperf 目前已停止维护,但我不确定它是否会有多大帮助,因为 DOM 操作的效率在浏览器和应用程序细节之间差异很大。

我建议的第一件事是一套"微效率",这甚至可能没有多大帮助,但仍然是很好的做法。保留对 DOM 元素的引用数组,这样您就不必经常调用getElementById。虽然getElementById非常快,但它仍然是一个可以避免的函数调用。您可能认为数组会占用大量内存,但实际上您并没有将 DOM 元素存储在数组中,而是存储指向 DOM 元素的指针。此外,还可以保留对项length的引用,以便不会在每次循环迭代时计算它:

const myDivs = [/* populate this array with your DOM elements */];
for (var i = 0, l = IDs.length; i < l; i++) { 
    myDivs[i].innerHTML = Variables[i];
}

另一件重要的事情是在执行繁重的 DOM 操作之前等待动画帧。您可以在此处阅读有关requestAnimationFrame的更多信息。

最后,您只需要进行测试。正如有人在评论中建议的那样,最好的选择是在不使用 DOM 的情况下直接进行 DOM 操作innerHTML .这样做的原因是innerHTML需要解析和渲染树构造,这是昂贵的。直接 DOM 操作的一个例子是...假设您想从此状态开始:

<div id="ID[1]">
  <img src="foo.jpg" />
</div>

。到此状态:

<div id="ID[1]">
  <h1>Hello</h1>
  <img src="foo.jpg" />
</div>

我们刚刚添加了一个 H1 - 你会写这样的东西:

const h1 = document.createElement('h1');
h1.innerText = 'Hello';
const div = document.getElementById('ID[1]');
div.insertBefore(h1, div.firstChild);

但如您所见,这需要您在之前和之后的状态之间进行"差异",并计算从一个状态到另一个状态的最有效方法。碰巧的是,这是 ReactJS 和其他虚拟 DOM 库非常有效地做的事情 - 所以你可以尝试其中一个库。

如果您反对使用库,或者认为您的 DOM 波动太大,以至于内存中差异效率很高,那么您可以尝试构造一个 DOM 字符串并尽可能少地使用 innerHTML。例如,如果你的 DOM 看起来像这样:

<div id="main-container">
  <div id="ID[1]">...</div>
  <div id="ID[2]">...</div>
  <div id="ID[3]">...</div>
  ...
</div>

然后尝试执行以下操作:

let html = '';
const container = document.getElementById('main-container');
for (let i = 0, l = IDs.length; i < l; i++) {
  html += `<div id="ID[${i}]">${Variables[i]}</div>`;
}
// you want to set innerHTML as few times as possible
container.innerHTML = html;

最新更新