Подтвердить что ты не робот

Глубокое клонирование и настройка innerHTML: что быстрее?

Я пытаюсь выяснить наиболее эффективный способ глубокого клонирования дерева DOM в браузере.

Если я начинаю с

var div = document.getElementById("source");
var markup = div.innerHTML;

Что будет быстрее,

var target = div.cloneNode(true);

или

var target = document.cloneNode(false);
target.innerHTML = markup;

Я понимаю, что платформа браузера может иметь большое значение здесь, поэтому любая информация о том, как эти сравнения в реальном мире будут оценены.

4b9b3361

Ответ 1

Пусть тест!

Я добавил следующий код к копии страницы "Вопросы StackOverflow" (сначала удалив существующие сценарии и запускаясь с нуля, когда один из timecom() s раскомментирован каждый раз, три пробега из 100 операций:

function timeit(f) {
    var start= new Date();
    for (var i=100; i-->0;) {
        f();
    }
    return new Date()-start;
}

var c= document.getElementById('content');
var clones= [];

//alert('cloneNode: '+timeit(function() {
//    clones.push(c.cloneNode(true));
//}))

//alert('innerHTML: '+timeit(function() {
//    var d= document.createElement('div');
//    d.innerHTML= c.innerHTML;
//    clones.push(d);
//}))

Вот результаты, которые запускаются на VirtualBox на Core 2 Q9300:

IE7
cloneNode: 3238, 3235, 3187
innerHTML: 8442, 8468, 8552

Firefox3
cloneNode: 1294, 1315, 1289
innerHTML: 3593, 3636, 3580

Safari3
cloneNode: 207, 273, 237
innerHTML: 805, 818, 786

Chrome1
cloneNode: 329, 377, 426
innerHTML: 2327, 2536, 2865

Opera10
cloneNode: 801, 791, 771
innerHTML: 1852, 1732, 1672

Итак, cloneNode (true) намного быстрее, чем копирование innerHTML. Конечно, это всегда было; сериализация DOM для текста, а затем повторная обработка его из HTML - тяжелая работа. Причина, по которой дочерние операции DOM, как правило, медленны, заключается в том, что вы вставляете/перемещаете их один за другим; все операции DOM, такие как cloneNode, не должны делать этого.

Safari умеет делать innerHTML op удивительно быстро, но все же не так быстро, как это делает cloneNode. IE, как и ожидалось, является собакой.

Таким образом, авто -1 для всех, кто сказал, что innerHTML, очевидно, будет быстрее, не учитывая, что на самом деле делал вопрос.

И да, jQuery использует innerHTML для клонирования. Не потому, что быстрее, - читайте источник:

// IE copies events bound via attachEvent when
// using cloneNode. Calling detachEvent on the
// clone will also remove the events from the orignal
// In order to get around this, we use innerHTML.

jQuery использует Element.attachEvent() для реализации собственной системы событий, поэтому, естественно, это должно избежать этой ошибки. Если вам это не нужно, вы можете избежать накладных расходов.

[Отключить тему: опять же, я думаю, что сохранение jQuery в качестве вершины лучшей практики может быть немного ошибочным, особенно учитывая следующую строку:

html.replace(/ jQuery\d+="(?:\d+|null)"/g, "")

Это право - jQuery добавляет свои собственные произвольные атрибуты к элементам HTML, а затем должен избавиться от них, когда он клонирует их (или иным образом дает доступ к их разметке, например, методом $(). html())., Это довольно уродливо, но тогда он думает, что лучший способ сделать это - обработка HTML с использованием регулярного выражения, которое является основной ошибкой, которую вы ожидаете от наивных 1-репутационных SO-опросников, чем автор Second Coming Best JS Framework Evar.

Надеюсь, у вас не было строки "jQuery1 =" 2 "в любом месте вашего текстового контента", потому что если вы просто загадочно потеряли ее. Спасибо jQuery! Таким образом, исключает вне темы.]

Ответ 2

Хммм... интересно, я просто сделал тест в Firefox 3, а глубокий клон, по-видимому, примерно в 3 раза быстрее, чем маршрут innerHTML.

Я уверен, что innerHTML все еще быстрее, чем отдельные операции DOM, но, по крайней мере, для глубокого клонирования, cloneNode (true) лучше оптимизирован.