Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> innerHTML или createElement? Небольшой тест с полезными последствиями 
:(
    Опции темы
Ghirik
Дата 28.5.2008, 04:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 919
Регистрация: 26.3.2007

Репутация: 13
Всего: 20



Собрался оптимизировать один свой старый скриптик под новую задачу, но оказалось, что всё написано не так... И как всегда, проще написать заново. Но раз уж заново, значит и подойти к вопросу следует обтсоятельно. Подошел... Загрузился вопросом о самом быстром создании элементов -  innerHTML или createElement?

Нарисовал страничку. (осторожней с Мозиллой, открывайте отдельным процессом.)

Ну, и код...

Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Title block</title>
<script type="text/javascript">
<!-- // --><![CDATA[

var old = 0;

function milliSec() {
    var t = new Date();
    if (old == 0) {
        old = t.valueOf();
    }
    else {
        tmp = t.valueOf() - old;
        old = 0;
        return tmp;
    }
}

function qwe() {
    
}

function domCreationDiv() {
    var i = 400;
    milliSec();
    while (i--) {
        var div = document.createElement('div');
        div.setAttribute('id', "div" + i);
        div.style.width = 0 + 'px';
        div.style.height = i + 'px';
        div.style.border = '1px solid #0000FF';
        /*@cc_on 1 | @*/ 0 ? div.style.styleFloat = 'left' : div.style.cssFloat = 'left';
        div.onclick = qwe;
        document.getElementById('td').appendChild(div);
    }
    if (document.getElementById('time0').innerHTML == "") document.getElementById('time0').innerHTML = milliSec() + ' milliseconds';
    else if (document.getElementById('time1').innerHTML == "") document.getElementById('time1').innerHTML = milliSec() + ' milliseconds';
    else if (document.getElementById('time2').innerHTML == "") document.getElementById('time2').innerHTML = milliSec() + ' milliseconds';
}

function innerHTMLCreationDiv() {
    var i = 400;
    milliSec();
    while (i--) {
        document.getElementById('td').innerHTML += "<div style='border: 1px solid #0000FF; width: 0px; height: " + i + "px; float: left;' id='div'" + i + " onclick='qwe()'></div>";
    }
    if (document.getElementById('time3').innerHTML == "") document.getElementById('time3').innerHTML = milliSec() + ' milliseconds';
    else if (document.getElementById('time4').innerHTML == "") document.getElementById('time4').innerHTML = milliSec() + ' milliseconds';
    else if (document.getElementById('time5').innerHTML == "") document.getElementById('time5').innerHTML = milliSec() + ' milliseconds';
    
}

function cleanAll() {
    for (var i = 0; i < 5; i++) {
        document.getElementById("time" + i).innerHTML = "";
    }
    document.getElementById("td").innerHTML = "";
}

// ]]>
</script>
</head>
<body>
<table width="100%" id="table1" cellspacing="0" cellpadding="0" style="border:1px solid #0000FF; border-collapse: collapse">
    <tr>
        <td width="55%" style="border: 1px solid #0000FF">Time of generation <b>createElement</b></td>
        <td id="time0" width="15%" style="border: 1px solid #0000FF" align="right"></td>
        <td id="time1" width="15%" style="border: 1px solid #0000FF" align="right"></td>
        <td id="time2" width="15%" style="border: 1px solid #0000FF" align="right"></td>
    </tr>
    <tr>
        <td style="border: 1px solid #0000FF">Time of generation <b>innerHTML</b></td>
        <td id="time3" style="border: 1px solid #0000FF" align="right"></td>
        <td id="time4" style="border: 1px solid #0000FF" align="right"></td>
        <td id="time5" style="border: 1px solid #0000FF" align="right"></td>
    </tr>
    <tr>
        <td style="border: 1px solid #0000FF"><input type="button" value="createElement" onclick="domCreationDiv()"><input type="button" value="innerHTML" onclick="innerHTMLCreationDiv()"><input type="button" value="cleanAll" onclick="cleanAll()"></td>
        <td style="border: 1px solid #0000FF" align="right"></td>
        <td style="border: 1px solid #0000FF" align="right"></td>
        <td style="border: 1px solid #0000FF" align="right"></td>
    </tr>
    <tr>
        <td id="td" colspan="4" height="400"></td>
    </tr>
</table>
</body>
</html>


Над кодом не смеяться! Лепил как попало....

Скорость Оперы поражает воображение....  smile 

Mozilla, при создании через createElement, как то, хитровы...ано выдает результат... У меня старенький P4 3GHz, дак Mozilla, на первое нажатие кнопки "createElement" визуально значительно медленнее срабатывает чем IE, но время показывает всего раза в полтора большее. А если нажимаю второй раз, то уходит на долго в штопор... но после выхода, время опять то-же!  smile 



Это сообщение отредактировал(а) Ghirik - 28.5.2008, 05:55


--------------------
Отдадим всё клиенту, пускай его машина мучается...

PM MAIL   Вверх
Ghirik
Дата 28.5.2008, 06:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 919
Регистрация: 26.3.2007

Репутация: 13
Всего: 20



Ну, собственно, этого и следовало ожидать. innerHTML - обычная строка, и, разумеется, браузеры тратят неимоверное количество ресурсов, чтобы распарсить в ней каждый элемент. Но почему бы это не сделать один раз, а потом (в цикле) при совпадении строковых значений просто создавать элементы по старой схеме. Ан нет... парсится каждый вывод innerHTML.


--------------------
Отдадим всё клиенту, пускай его машина мучается...

PM MAIL   Вверх
bars80080
Дата 28.5.2008, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 15
Всего: 315



значит, однозначно заниматься креатэлементизмом?
PM MAIL WWW   Вверх
SelenIT
Дата 28.5.2008, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 49
Всего: 401



innerHTML несколько быстрее (особенно в IE), но, насколько мне известно, сбрасывает некоторые изменения DOM (напр. значения и состояния динамически добавленных элементов форм), поэтому для высокодинамичных страниц может привести к непредсказуемым последствиям. DOM-методы в общем случае медленее, зато надежнее.


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
bars80080
Дата 28.5.2008, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 15
Всего: 315



хм, а мне показалось, что Ghirik говорит о том что inner наоборот тяжеле переваривается браузерами (больше ресурсов != больше времени ?)


у меня просто есть ситуация, где я генерирую много таблиц из данных средствами DOM, а часть innerHTML (вложенные слои)
нужно ли полностью переводить на DOM?
PM MAIL WWW   Вверх
SelenIT
Дата 28.5.2008, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 49
Всего: 401



Цитата(bars80080 @  28.5.2008,  13:33 Найти цитируемый пост)
много таблиц из данных

Если кроме этого навороченной динамики на странице нет, лично я бы оставил innerHTML. Как раз в случае таблиц разница в скорости особенно заметна.


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
bars80080
Дата 28.5.2008, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 15
Всего: 315



страх какой, пошла идея прахом... впрочем доведу и выложу, там отладим как лучше
PM MAIL WWW   Вверх
Ghirik
Дата 28.5.2008, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 919
Регистрация: 26.3.2007

Репутация: 13
Всего: 20



Цитата

страх какой, пошла идея прахом... 


Ну, не совсем...  smile  
Я то ж, всё анимацией занимаюсь, потому для меня результат остался результатом.

Ужас... smile  Как плохо у IE с генерацией таблиц.... А это, пожалуй, один из основных элементов в вэбе. Если Mozilla так чудненько справляется с табличками, попробую провести тест динамического изменения размеров таблиц и дивов. А вдруг, динамика с таблицами пойдет лучше... Меня сейчас сильно интересует одновременное плавное изменение размеров у 5-20 элементов на странице, потому и начал эти тестирования. Скоро выложу последнее решение по плавному движению, выкинул полностью все вычисления из динамического процесса. Потестируем...


--------------------
Отдадим всё клиенту, пускай его машина мучается...

PM MAIL   Вверх
IDVsbruck
Дата 29.5.2008, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 778
Регистрация: 12.11.2006

Репутация: 8
Всего: 22



Я тоже давно перешел на DOM - это грамотнее и быстрее (в работе). Единственное - из-за величин проектов не всегда хочется уделять столько времени созданию структуры, проще всунуть все в innerHTML.
Иногда и вовсе без DOM не обойтись ... особенно в динамических проектах.
А иногда вывод возможен только через innerHTML - например, вывод кусков страницы, полученных по ajax'у - иначе можно задолбаться самому парсить код или, что еще утомительней - создавать структуру на сервере, которую сможет обрабатывать клиент.
Так что вопрос удобства остается на совести каждого, но скорость почти (!) всегда за DOM'ом. Почти - это потому, что td_element.innerHTML = "aaa" будет быстрее, чем td.element.insertAdjacentText("afterEnd", "aaa") или что-то типа var aaa = "aaa"; td_element.appendChild(aaa).
PM MAIL   Вверх
Itsys
Дата 30.5.2008, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1338
Регистрация: 21.1.2008
Где: г. Москва

Репутация: 12
Всего: 34



IE 7  smile 
Time of generation createElement 125 milliseconds   
Time of generation innerHTML 57437 milliseconds 

PM MAIL WWW Skype   Вверх
bars80080
Дата 30.5.2008, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 15
Всего: 315



Itsys, таблицы?

или это не тест, а откудато взято?
PM MAIL WWW   Вверх
SelenIT
Дата 30.5.2008, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 49
Всего: 401



Это, похоже, результат теста Ghirikа из первого поста на какой-то достаточно слабой машине. Никто не спорит, множественное изменение innerHTML в цикле - жестокий крэш-тест для браузера, это, имхо очевидно. Сравнивать есть смысл два следующих подхода - непосредственная работа с DOM (createElement+appendChild etc.) vs. генерация общего кода нужной разметки в виде строки и однократное внедрение ее в нужное место через innerHTML. Именно к этому сравнению относятся тест http://www.quirksmode.org/dom/innerhtml.html и мои комменты здесь smile.


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
JSman
Дата 7.6.2008, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 279
Регистрация: 10.7.2006

Репутация: нет
Всего: 4



Код

function innerHTMLCreationDiv() {
    var i = 400;
    milliSec();
    while (i--) {
        document.getElementById('td').innerHTML += "<div style='border: 1px solid #0000FF; width: 0px; height: " + i + "px; float: left;' id='div'" + i + " onclick='qwe()'></div>";
    }
    if (document.getElementById('time3').innerHTML == "") document.getElementById('time3').innerHTML = milliSec() + ' milliseconds';
    else if (document.getElementById('time4').innerHTML == "") document.getElementById('time4').innerHTML = milliSec() + ' milliseconds';
    else if (document.getElementById('time5').innerHTML == "") document.getElementById('time5').innerHTML = milliSec() + ' milliseconds';
    
}


тест написан совершенно неверно, так как
1. document.getElementById('td') - каждый раз вызываем поиск элемента с указанными id
2. while (i--) {
        document.getElementById('td').innerHTML += "<div style='border: 1px solid #0000FF; width: 0px; height: " + i + "px; float: left;' id='div'" + i + " onclick='qwe()'></div>";
    }

используется контактация строк, причем неоптимизированная. 



PM ICQ   Вверх
Ghirik
Дата 7.6.2008, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 919
Регистрация: 26.3.2007

Репутация: 13
Всего: 20



Цитата

тест написан совершенно неверно,


Понятное дело, всё на скорую руку...

Цитата

1. document.getElementById('td') - каждый раз вызываем поиск элемента с указанными id


Ну и что? Количество вызовов метода везде одинаковое. Как это может повлиять на достоверность относительных величин?

Цитата

используется контактация строк


Не знаком с этим понятием, хоть и использовал. smile  Что такое контактация строк?


--------------------
Отдадим всё клиенту, пускай его машина мучается...

PM MAIL   Вверх
JSman
Дата 8.6.2008, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 279
Регистрация: 10.7.2006

Репутация: нет
Всего: 4



Если мы хотим сравнить быстродействие 2 возможностей, то должны снизить влияние иных методов на результат.

поэтому из цикла должны убрать поиск по id. Каждый раз этот метод инициализируется и затрачивает время. действительно, что он вызывается равное количество раз в обоих случаях. Ну, это ладно.

На результаты теста сильно влияет контактация строк - сложение фрагментов строки в целое. В Js эта операция совершенно не оптимизирована. Как это исправить:
имеем 2 строки: a + b. получим гораздо быстрее результат, если сделаем так: [a,b].join(''). то есть используем только push и join вместо привычного +. почитайте ppk.

innerHTML имеет сеттер. зачем его каждый раз вызывать, если достаточно одного раза присваиванием одной строки к innerHTML
PM ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0924 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.