IE sp62
Firefox 2.0.0.12
Opera 9.22
Safari 3.04b
offsetHeight
23500
10624
4453
5140
isHidden
231
351
70
71
isHidden2
370
792
212
118
offsetHeight vs. isHidden
102 раза
30 раз
73 раза
92 раза
Таблица 6.5. Резульаты выполнения функции isHidden. Времена приведены в миллисекундах
Как показывают тесты, даже при большой вложенности падение скорости невелико. Таким образом, мы получили универсальное решение, которое быстрее доступа к offsetHeight в 30–100 раз.
Заключение
Все вышеприведенные мысли предназначены не столько для решения проблемы выяснения видимости элемента в общем случае, сколько для объяснения одного из наиболее часто встречающихся узких мест взаимодействия с DOM и детального разбора методов оптимизации. В ходе тестов был намеренно воспроизведен наихудший случай. В реальных ситуациях такой прирост скорости получится только при использовании в анимации. Однако понимание причин и механизма reflow позволяет писать более оптимальный код.
В качестве послесловия: стили или классы?
В заключении давайте затронем еще несколько оптимизационных моментов, связанных с отображением HTML-страницы на экране браузера. Пусть в нашем документе есть элементы, у которых нужно поменять цвет, фон или что-нибудь еще, относящееся к стилям. Например, подсветить строки таблицы при наведении мыши или пометить их, если выбрана соответствующая галочка в форме.
Существует два способа это сделать: при помощи стилей или установив цвет (или фон) напрямую из JavaScript. Для начала немного кода — с помощью класса:
var items = el.getElementsByTagName('li');
for (var i = 0; i < 1000; i++) {
items[i].className = 'selected'
}
И с помошью стилей:
var items = el.getElementsByTagName('li');
for (var i = 0; i < 1000; i++) {
items[i].style.backgroundColor = '#007f00';
items[i].style.color = '#ff0000';
}
Результаты простые и понятные:
Метод
IE 6
IE 7
Firefox 1.5
Firefox 2.0
Opera 9
element.className
512
187
291
203
47
element.style.color
1709
422
725
547
282
Таблица 6.6. Применение стилей и классов к элементам
Перерисовка страницы
Однако когда мы изменяем класс элемента, код отрабатывает значительно быстрее, но вот страница обновляется медленно. Это все из-за того, что изменение свойства className не перерисовывает страницу мгновенно, вместо этого браузер просто помещает событие обновления в очередь reflow. Отсюда и огромная скорость, казалось бы, более сложной процедуры. А что по поводу :hover? К сожалению, :hover работает только для ссылок в Internet Explorer 6. Поэтому в любом случае придется пользоваться какой-то его эмуляцией.
Из всего вышеперечисленного можно сделать два ключевых вывода
Используйте className везде, где это возможно. Это дает больше гибкости и контроля над внешним видом сайта.
Если на странице много элементов в контейнере и необходимо построить очень быстрый интерфейс, стоит устанавливать стили напрямую через свойство style.
Групповое изменение стилей
Если мы уже задумались над максимально быстрым изменением интерфейса нашего веб-приложения (отрисовке) через свойство style, то стоит иметь в виду следующий момент. Мы можем изменять свойство cssText, которое отвечает за компилируемые стили элемента:
element.style.cssText = "display:block;width:auto;height:100px;...";
Таким образом, мы можем дополнительно ускорить наше единовременное обновление стилей у элемента, потому что произойдет всего одно присвоение свойств и всего один reflow (и он случится сразу же после изменения этого свойства, а не в отложенном режиме).
Два слова о таблицах
Таблицы замечательно подходят для организации информации. Однако если в HTML-документе встречается таблица, то браузеру приходится пробежаться по ней дважды: в первый раз — чтобы выбрать все элементы, рассчитать их взаимные размеры, и чтобы отрисовать их все — во второй раз. Если на странице выводятся большие массивы данных (например, параметры товаров или статистические данные), то гораздо быстрее будет визуализировать такие таблицы в один проход.
Давайте рассмотрим, как можно помочь браузерам в их нелегком труде. Следующие действия позволят начать отображение таблицы еще до того, как будет получена вся информация о ней.