我有一个关于页面速度和代码优化的问题。我有一个几乎 100% 通过 AJAX 调用填充的页面。我的问题是:将几个空的 div、span 等编码到页面的 HTML 中,然后使用 javascript 填充这些元素是否更快?或者,在 javascript 中创建这些元素并插入和追加它们是否更快? 我也不确定是否有很大的区别。因此,我们将不胜感激这方面的任何帮助/建议。
最佳答案
几年前,我对此做了一个实验。分配给元素的 innerHTML
属性来创建复杂结构比使用重复的 createElement
appendChild
insertBefore 要快得多
等调用。我已经挖出了我所做的关于它的帖子(到 Prototype & script.aculo.us 邮件列表);下面。
请记住,快速解析 HTML 并渲染它是浏览器的工作,并且浏览器为此进行了高度优化。如果您将一个包含复杂 HTML 结构的字符串分配给容器元素的 innerHTML
属性,那么您将在 JavaScript 层到浏览器渲染层之间进行一次行程。浏览器的解析和渲染代码可以不间断地进行。
相比之下,如果您使用 DOM API 构建一些复杂的结构,不仅会发生大量跨层旅行(JavaScript -> 浏览器 -> JavaScript),而且浏览器也必须工作使用 DOM API 而不是其内部结构。
因此,通常值得考虑一个编写良好的 JavaScript 模板引擎(如果您想在客户端执行此操作)。这些通常会将模板“编译”成易于处理的形式,并且在处理特定数据集期间,他们将使用一些技巧,例如通过 Array#push 将字符串构建为数组中的片段,然后通过传入 ""
作为分隔符的 Array#join
得到最终结果。对于大字符串,这可能比字符串连接更快,尽管它是否(以及达到什么程度)非常取决于实现(Firefox 的 SpiderMonkey 与 Chrome 的 V8 与 IE 的 JScript),与 innerHTML
与 DOM 的比较,它们的区别仅在于它的速度快多少。
Here's the mailing list几年前我正在谈论的消息(基本上就是我上面所说的;哇,那是两年前了),here's the Pastie它指的是,这就是copied to JSBin ,最后...这是代码:(请注意,该代码不是旨在成为永远的美丽和欢乐,这是一个快速破解...尽管如此,是的,两年后,我想我现在可以更好地编写一些东西。)
可能值得将其转换为适用于 jsPerf 的东西。恐怕现在没时间这样做。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style>
#log {
border-bottom: 1px solid black;
}
#log p {
margin: 0;
padding: 0;
}
</style>
<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/prototype/1/prototype.js'></script>
<script type='text/javascript'>
document.observe('dom:loaded', function() {
$('btnDOMDirect').observe('click', useDOMDirect);
$('btnPrototypeDOM').observe('click', usePrototypeDOM);
$('btnHTML').observe('click', useHTML);
});
var numRows = 10;
var numCols = 10;
function usePrototypeDOM(evt)
{
var table;
var tbody;
var tr;
var td;
var row;
var col;
var start;
var end;
start = (new Date()).getTime();
table = new Element('table');
tbody = new Element('tbody');
table.appendChild(tbody);
for (row = 0; row < numRows; ++row) {
tr = new Element('tr');
tbody.appendChild(tr);
for (col = 0; col < numCols; ++col) {
td = new Element('td');
td.update('Row ' + row + ', col ' + col);
tr.appendChild(td);
}
}
$('targetTable').update(table);
end = (new Date()).getTime();
log('DOM took ' + (end - start) + 'ms');
}
function useDOMDirect(evt)
{
var table;
var tbody;
var tr;
var td;
var row;
var col;
var start;
var end;
if (Prototype.Browser.IE) {
alert("DOM direct doesn't work on IE because I used table elements. Sorry. The other two work.");
return;
}
start = (new Date()).getTime();
table = document.createElement('table');
tbody = document.createElement('tbody');
table.appendChild(tbody);
for (row = 0; row < numRows; ++row) {
tr = document.createElement('tr');
tbody.appendChild(tr);
for (col = 0; col < numCols; ++col) {
td = document.createElement('td');
td.update('Row ' + row + ', col ' + col);
tr.appendChild(td);
}
}
$('targetTable').update(table);
end = (new Date()).getTime();
log('DOM took ' + (end - start) + 'ms');
}
function useHTML(evt)
{
var html;
var row;
var col;
var start;
var end;
start = (new Date()).getTime();
html = '<table><tbody>';
for (row = 0; row < numRows; ++row) {
html += '<tr>';
for (col = 0; col < numCols; ++col) {
html += '<td>Row ' + row + ', col ' + col + '</td>';
}
html += '</tr>';
}
html += '</tbody></table>';
$('targetTable').update(html);
end = (new Date()).getTime();
log('HTML took ' + (end - start) + 'ms');
}
function log(msg)
{
var l;
var p;
l = $('log');
if (l) {
p = new Element('p');
p.update(msg);
l.appendChild(p);
}
}
</script>
</head>
<body>
<input type='button' id='btnDOMDirect' value='DOM Direct' />
<input type='button' id='btnPrototypeDOM' value='Prototype DOM' />
<input type='button' id='btnHTML' value='HTML' />
<div id='log'></div>
<div id='targetTable'></div>
</body>
</html>
关于javascript - 页面速度优化: writing to DOM using javascript vs. html,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5408829/