Chr*_*sOh 9 javascript performance dom
从用户体验来看,下面哪种技术更好?
在这两个示例中,假设将thumbContainer其设置为返回值document.getElementById('thumbContainer'),并new Thumbnail(thumb).toXMLString()返回其中包含XHTML标记的字符串.
A)简单地+=用thumbContainer.innerHTML:
for (thumb in thumbnails) {
thumbContainer.innerHTML += new Thumbnail(thumb).toXMLString();
}
Run Code Online (Sandbox Code Playgroud)
B)或转换new Thumbnail(thumb).toXMLString()为DOM元素并使用appendChild?
for (thumb in thumbnails) {
var shell = document.createElement('div');
shell.innerHTML = new Thumbnail(thumb).toXMLString();
for (i = 0; i < shell.childElementCount; i++) {
thumbContainer.appendChild(shell.children[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经使用了两者并得到了Firefox的投诉,我有一个长期运行的脚本,我想要阻止它吗?
哪个循环不太紧,这将允许UI在新元素添加到DOM时更新?
bob*_*nce 10
A)使用thumbContainer.innerHTML简单地+ =
永远不要这样做.这必须将所有内容序列化为HTML,向其中添加一个字符串,并将其全部解析回来.它很慢(在循环中执行它是特别糟糕的新闻)并且它将丢失所有JavaScript引用,事件处理程序等等.
IE insertAdjacentHTML会更有效地做到这一点.它也是HTML5的一部分,但尚未在其他地方广泛实施.
使用appendChild?
是的,没关系.如果你有很多拇指,它会开始变慢(但不会像每次重新训练innerHTML那样糟糕).在某些情况下,使DocumentFragment一次将多个元素插入容器子节点列表可能会有所帮助.将DocumentFragment与Range相结合可以做得更多,但是由于IE的Range实现是如此StRange,因此难以兼容地编写.
无论哪种方式,因为您似乎没有对单个shell节点做任何事情,为什么不在解析之前简单地将所有thumbernail HTML字符串连接在一起?
for(shell.childNodes中的var child){
不要for..in在序列类型上使用,它不会做你想象的.它仅用于反对Object用作映射.迭代Array或NodeList的正确方法很简单for (var i= 0; i<sequence.length; i++).
就个人而言,我更喜欢第二种方法(使用appendChild),因为您在不影响旧元素的情况下向文档树添加新元素.
使用innerHTML + = new内容时,会影响旧内容,因为必须重新分配所有HTML(替换为包含旧代码和一些新代码的新HTML).
但是,如果你想提高性能,我建议使用DocumentFragments.使用它们,您可以在文档树上只添加一个appendChild调用附加整组节点.值得一读:John Resig撰写的"DOM DocumentFragments",但问题并非如此,因为您将内容作为字符串获取,您必须首先转换为DOM节点.
我的第二个建议是,创建一串HTML代码,然后在临时容器上使用innerHTML将其转换为DOM节点
var htmlCode = "";
for (thumb in thumbnails) {
htmlCode += new Thumbnail(thumb).toXMLString();
}
var element = document.createElement(htmlCode);
element.innerHTML = htmlCode; // ... and append all the elements to document, or thumbContainer.innerHTML += htmlCode;
Run Code Online (Sandbox Code Playgroud)