Оптимизация JavaScript часть 2: Применение стилей к элементам

(JavaScript) · English (16,337 views)

Это вторая часть цикла статей, посвященных оптимизации JavaScript. В этой заметке я рассмотрю динамическое изменение стилей элементов и немного раскрою процесс рендеринга HTML. Кроме того, в этой заметке вы найдете некоторые трюки, позволяющие сделать Ваши приложения быстрее.

Сценарий: Ваш документ содержит элементы, у которых нужно поменять цвет, фон или что-нибудь еще, относящееся к стилям. Например, подсветить строки таблицы при наведении мыши или пометить их, если выбран соответствующий чекбокс.

И снова, я знаю два способа: используя стили или установив цвет (или фон) напрямую из JavaScript. Для начала немного тестов:

1
2
3
4
var items = el.getElementsByTagName('li');
for (var i = 0; i < 1000; i++) {
    items[i].className = 'selected';
}

Средний результат 187 – 291 мс, для InternetExplorer 6 время составило 512 мс, и в Opera 9 оно равно 47 мс.

1
2
3
4
5
var items = el.getElementsByTagName('li');
for (var i = 0; i < 1000; i++) {
    items[i].style.backgroundColor = '#007f00';
    items[i].style.color = '#ff0000';
}

Я получил результаты, начинающиеся с 282 мс в Opera 9 и заканчивающиеся 1709 мс в Internet Explorer 6.

Результаты простые и понятные:

No Method IE 6 IE 7 FF 1.5 FF 2.0 Opera 9
1 element.className 512 187 291 203 47
2 element.style.color 1709 422 725 547 282

Тест производительности: Применение стилей к элементам

Вы можете посмотреть тест и получить собственные результаты производительности здесь.

Похоже на то, что это самая малозначимая статья цикла, но... есть одна штука с Internet Explorer - обновление страницы. Помните сценарий, описанный в начале статьи, об onmouseover? Когда Вы изменяете имя класса элемента, Ваш код значительно быстрее отрабатывает, но вот страница обновляется медленно. Взгляните на пример. Попробуйте кликнуть "Generate elements", когда выбрана опция "element.className". Попробуйте подвигать мышкой над элементами, проскроллить список до конца и подвигать снова (для медленных машин количество элементов будет меньше установленного по умолчанию, для более быстрых - больше). Вы заметили, что фон сильно отстает от курсора мыши? Теперь переключите на "element.style.color" (не забудьте снова нажать "Generate elements"). Фон изменяется более плавно, правда?

Внизу страницы вы видите количество пойманных событий onmouseover и среднее время, потраченное на их обработку. Как Вы могли заметить, в первом случае код отрабатывает более чем в два раза быстрее! Почему же выглядит медленнее? Я думаю, все из-за того, что изменение свойства className в Internet Explorer не перерисовывает страницу мгновенно, вместо этого он просто помещает событие обновления в очередь. Отсюда и огромная скорость, казалось бы, более сложной процедуры. Если у Вас есть другие идеи, пожалуйста, отпишитесь в комментариях.

Те, кто дочитал до этого места, наверняка скажут: "Ээээ, товарищ, ты хитришь. А где же :hover?". Спешу исправить положение и дописываю этот вариант. Во-первых, эта штука не работает в Internet Explorer 6 (и не надо спрашивать "кому он нужен?"). Но это не самая большая проблема, намного хуже дела обстоят с производительностью. Даже комментировать не хочу, просто выберите третий радиобаттон на приведенной выше странице и подвигайте мышью в Internet Explorer 7 и Opera 9.

Выводы

  • Используйте className везде, где это возможно. Это дает Вам больше гибкости и контроля над внешним видом сайта.
  • Если у Вас много элементов в контейнере, и необходимо построить очень быстрый интерфейс, устанавливайте стили напрямую через свойство style элементов.

Ссылки на другие части

  • Часть 1: Добавление элементов DOM в документ
  • Часть 2: Применение стилей к элементам
  • Часть 3: Подписка на события
  • Часть 4: Анонимные функции (будет опубликовано скоро)
  • Часть 5: Подписка на события по требованию (будет опубликовано скоро)
  • Часть 6: Отображение и скрытие элементов (будет опубликовано скоро)
  • Часть 7: Перечисление элементов коллекции (будет опубликовано скоро)

4 Responses to this entry

Subscribe to comments with RSS

said on 27.03.2007 at 23.25 · Permalink

Критик, спасибо! Я довольно часто задавался вопросом, что лучше использовать и вот выбор стал для меня очевиден. Жду новых статей из данного цикла.

P.S. Вот хотел поделиться. http://htmlbook.ru/css/ – очень хороший справочник для web-разработчика. В конце описания каждого параметра CSS приводится способ доступа к нему из JavaScript

said on 17.02.2008 at 13.04 · Permalink

ммм, я бы добавил одно уточнение по поводу :hover. Фактически, он становится нужен только для подсветки строк в таблицах (все остальное делается через семантическую верстку и обычный a:hover).

Но для интерфейсов с таблицами, имхо, больше 50 строк на странице вообще делать вредно. В общем, классы скорее рулят, чем нет.

Vitazi
said on 03.03.2009 at 22.43 · Permalink

Достаточно странно конечно.. но в opere AC все с точностью да наоборот)) и ховер оказывается самым шустрым)) а вот ClasseName просто жутко тормозит..

Иван
said on 04.03.2009 at 16.45 · Permalink

По поводу изменения страницы в internet explorer я столкнулся с следующим поведением – страница обновляется позже завершения javascript. Т.е. выполнение оператора javascript вовсе не гарантирует немедленного обновления страницы.

Comments are closed

Comments for this entry are closed for a while. If you have anything to say – use a contact form. Thank you for your patience.