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

Источник: kpumuk

Часть 1

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

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

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

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

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

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 элементов.

Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=4924