页面速度优化:使用 javascript 与 html 写入 DOM
我有一个关于页面速度和代码优化的问题。我有一个几乎 100% 通过 AJAX 调用填充的页面。我的问题是:将几个空的 div、span 等编码到页面的 HTML 中,然后使用 javascript 填充这些元素是否更快?或者,在 javascript 中创建这些元素并插入和追加它们是否更快? 我也不确定是否有很大的区别。因此,我们将不胜感激这方面的任何帮助/建议。
I have a question concerning page speed and code optimization. I have a page which is populated almost 100% through AJAX calls. My question is: is it faster for me to code several empty divs, spans, whatever into the HTML of the page, then fill those elements using javascript? Or, is it faster to create these elements in javascript and insert and append them?
I'm not sure if there IS a big difference either. So, any help/advice in this area would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
几年前,我对此做了一个实验。分配给元素的
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 的比较,它们的区别仅在于速度快多少。这是我几年前谈论的邮件列表消息(基本上就是我上面所说的;哇,那是两年前的事了),这是它所指的 Pastie,这是复制到 JSBin,最后...这里是代码:(请注意,代码是 并不打算成为永远美丽和快乐的东西,这是一个快速破解......不过,是的,我想我现在会破解一些更好的东西,两年稍后。)
将其转换为可以在 jsPerf 上运行的东西可能是值得的。恐怕现在没有时间这样做。
A couple of years back, I did an experiment on this. It's much faster to assign to the
innerHTML
property of an element to create a complex structure than it is to use repeatedcreateElement
appendChild
insertBefore
etc. calls. I've dug up the post I did about it (to the Prototype & script.aculo.us mailing list); below.Remember that parsing HTML and rendering it quickly is what browsers do, and they're highly optimized to do it. If you assign a string with a complex HTML structure in it to a container element's
innerHTML
property, you're making one trip from the JavaScript layer to the browser's rendering layer, after which the browser's parsing and rendering code can proceed uninterrupted.In contrast, if you're building that some complex structure using the DOM API, not only is there a lot of cross-layer travel happening (JavaScript -> browser -> JavaScript), but the browser is also having to work with the DOM API rather than its internal structures.
Consequently, it's usually worth looking at a well-written JavaScript templating engine (if you want to do this client-side). These will usually "compile" the template once into an easily processed form, and during processing for a particular data set, they'll use tricks like building up the string as fragments in an array via
Array#push
, and then getting the final result viaArray#join
passing in""
as the separator. For large strings, that can be faster than string concatenation, although whether it is (and to what degree) is very implementation dependent (Firefox's SpiderMonkey vs. Chrome's V8 vs. IE's JScript), unlike theinnerHTML
vs. DOM thing, which only varies in how much faster it is.Here's the mailing list message from a couple of years back I was talking about (saying basically what I say above; wow, it was two years ago), here's the Pastie it refers to, here's that copied to JSBin, and finally...here's the code: (Note that the code is not intended to be a thing of beauty and a joy forever, it was a quick hack... Still though, yeesh, I'd like to think I'd hack up something a bit better now, two years later.)
It may be worth converting this into something that will work on jsPerf. No time to do that now, I'm afraid.
使用 javascript 来执行此操作总是会比较慢,因为它在页面加载之上运行,而不是像向 HTML 添加元素那样随页面加载运行。但是,您也可以说,如果没有 HTML 中的元素,页面的实际负载会较少(尽管不是很显着)。
但另一点是,JavaScript 在垃圾收集方面相当糟糕,因此如果您进行大量 DOM 调用,它最终会开始增加您的处理能力。
另外,如果您有兴趣维护语义网站,您是否需要标签?如果没有 JavaScript,它会优雅地降级吗?等等,我想这取决于你想要采取的角度。
It will always be slower using javascript to do this because it runs on top of the page load, rather than with it, as adding elements to the HTML would. However, you could also say that the actual load of the page is less (although not significantly) without having the elements in HTML.
The other point is, though, javascript is pretty bad at garbage collection so if you're making loads of DOM calls it will eventually start to add up in your processing power.
Plus there is also if you're interested in maintaining a semantic website, are you tags necessary? Does it degrade gracefully without javascript? Etc etc. It depends on the angle you are wanting to take I suppose.
如果您要创建大量元素,innerHTML 可能会更快,但它不是官方 DOM 标准的一部分(尽管它受到广泛支持)。我的建议是使用骨架布局来提供页面,在页面本身中包含尽可能多的 HTML,然后获取对页面相关部分的引用并使用标准 DOM 方法插入值。
这应该相当快,将使表示和逻辑分开,并且在未来站点更改或重新设计的情况下可能会变得更加灵活。
If you're creating lots of elements innerHTML can be much faster, however it's not a part of the official DOM standard (though it is widely supported). My recommendation would be to serve the page with a skeleton layout, including as much HTML as you can in the page itself, and then grab references to relevant parts of the page and plug in the values with standard DOM methods.
This should be reasonably fast, will keep the presentation and logic separate, and will probably end up being more flexible in the case of future site changes or redesigns.
修改
innerHTML
而不是使用 DOM 方法。根据 Quirksmode 上的W3C DOM 与innerHTML 基准,看起来所有测试的浏览器都是HTML 比 DOM 快得多。
Modify
innerHTML
instead of using DOM methods.According to this benchmark of W3C DOM vs innerHTML on Quirksmode, it looks like all tested browsers are much faster at HTML than DOM.