"virtual" DOM 操纵?



我知道进行多个DOM操作是不好的,因为它会迫使多个重新涂片。

即:

$('body').append('<div />')
         .append('<div />')
         .append('<div />')
         .append('<div />');

显然是一种更好的做法:

$('body').append('<div><div></div><div></div><div></div><div></div></div>');

,但我对虚拟操作感到好奇

即:

$('<div />').append('<div />')
            .append('<div />')
            .append('<div />')
            .append('<div />')
            .appendTo('body');

仍然很糟糕,显然多次致电功能会有一些开销,但是会有任何严重的性能命中吗?


我问的原因是:

var divs = [
    {text: 'First',  id: 'div_1', style: 'background-color: #f00;'},
    {text: 'Second', id: 'div_2', style: 'background-color: #0f0;'},
    {text: 'Third',  id: 'div_3', style: 'background-color: #00f;'},
    {text: 'Fourth', id: 'div_4', style: 'background-color: #f00;'},
    {text: 'Fifth',  id: 'div_5', style: 'background-color: #0f0;'},
    {text: 'Sixth',  id: 'div_6', style: 'background-color: #00f;'}
];
var element = $('<div />');
$.each(divs, function(i,o){
    element.append($('<div />', o));
});
$('body').append(element);

想象Divs数组来自一个数据库表,描述了一个表单(好的,我在示例中使用了Div,但是可以很容易地用输入替换)或类似的内容。

或使用我们拥有的"推荐"版本:

var divs = [
    {text: 'First',  id: 'div_1', style: 'background-color: #f00;'},
    {text: 'Second', id: 'div_2', style: 'background-color: #0f0;'},
    {text: 'Third',  id: 'div_3', style: 'background-color: #00f;'},
    {text: 'Fourth', id: 'div_4', style: 'background-color: #f00;'},
    {text: 'Fifth',  id: 'div_5', style: 'background-color: #0f0;'},
    {text: 'Sixth',  id: 'div_6', style: 'background-color: #00f;'}
];
var element = '<div>';
$.each(divs, function(i,o){
    element += '<div ';
    $.each(o, function(k,v){
        if(k != 'text'){
            element += k+'="'+v+'" ';
        }            
    });
    element += '>'+o.text+'</div>';
});
element += '</div>';
$('body').append(element);

首先,尽管可以阅读此类潜在的命中,但您应该始终开始衡量您是否有问题。

如果您无法感知问题,请编写最可读的代码。

如果您可以感知问题,测量,更改和测量。

说了所有这一切,您发布的最后一个示例涉及尚未写入DOM的元素,因此在appendTo将元素添加到DOM。

,如果您可以捕获第二和第三个示例之间的速度差异,我会感到非常惊讶 - 如果您可以看到其中任何一个的任何重大区别,很惊讶。

如果您在附加节点时真的很担心性能,则需要使用文档fragments。这些将使您无需重新涂抹即可将元素附加到DOM。约翰·辞职有一篇关于此主题的出色文章。他指出,性能增长了200-300%。我在我的一个应用程序中实施了文档范围,并可以确认他的主张。

运行时良好的旧标记生成发生了什么事?真的,发生了什么事?

我同意 @sohnee关于可读性重要性的观点,但是DOM操作是浏览器可以执行的最昂贵操作。保持一串标记的选项可以使其完美地阅读,并为用户体验可忽略不计。

在此jsperf中,我们正在运行时创建一个10x100表 - 数据分页的一个完全合理的(而不是最复杂的情况)。在运行Chrome最近版本的四核计算机上,直接DOM操纵脚本需要60毫秒才能完成,而不是3ms的标记缓存。

这在我的设置上是无法区分的,但是坐在公司防火墙后面的糟糕数字挑战的人呢?如果所需的DOM操作要较重,属性操纵并积极强迫重新定位/重新流程?

我要说的是,如果您想优化一些JavaScript,这不是一个开始的地方。

我认为,如果您开始到达这种代码是性能瓶颈的地步,则应使用模板而不是DOM操纵。

但是,是的,使用文档片段方法(将所有节点放在附加到DOM之前,将所有节点都放入独立的节点)在大多数情况下都会更快,几乎永远不会变慢。

  • http://mustache.github.com/
  • https://developers.google.com/cluse/templates/docs/helledorld_js
  • https://developer.mozilla.org/en-us/docs/javascript_templates

最新更新