Читать «Разгони свой сайт» онлайн - страница 90
Николай Мациевский
Замечание: в Opera reflow выполняется еще и по таймеру, что, однако, не мешает ей пройти тест быстрее остальных браузеров. Благодаря этому в Opera виден ход тестов — появляются добавляемые звездочки. Такое поведение оправдано, т.к. вызывает у пользователя ощущение большей скорости браузера.
Использование Computed Style
Что же показало тестирование? По меньшей мере, некорректно сравнивать универсальный (offsetHeight) и частный (style.display) случаи. Тестирование показало, что за универсальность надо платить. Если же все-таки хочется универсальности, то можно предложить другой подход: определение Computed Style — конечного стиля элемента (после всех CSS-преобразований).
getStyle = function()
{
var view = document.defaultView;
if(view && view.getComputedStyle)
return function getStyle(el,property)
{
return view.getComputedStyle(el,null)[property] ||
el.style[property];
};
return function getStyle(el,property)
{
return el.currentStyle && el.currentStyle[property] ||
el.style[property];
};
}();
Проведем тестирование этого способа и сведем все результаты в таблицу.
IE sp62
Firefox 2.0.0.12
Opera 9.22
Safari 3.04b
offsetHeight
23500
4453
4453
5140
style.display
171
56
56
34
getStyle
5219
5318
Во-первых, для IE и Firefox (наиболее популярных браузеров) функция эта работает некорректно (в общем случае возвращает неверные данные). Во-вторых, работает она чуть ли не медленнее, чем offsetHeight.
Вообще говоря, рекомендуется не пользоваться такими универсальными функциями (getStyle есть практически в каждой JavaScript-библиотеке), а реализовывать необходимую функциональность в каждом конкретном случае. Ведь если мы договоримся, что скрытые элементы должны иметь класс hide, то все сведется к определению наличия этого класса у элемента или его родителей.
Оптимизация: определение класса hide
Давайте подробнее остановимся на предложенном мной решении. Предлагаю следующую реализацию:
function isHidden(el)
{
var p=el;
var b=document.body;
var re=/(^|\s)hide($|\s)/;
while(p && p!=b && !re.test(p.className))
p=p.parentNode;
return !!p && p!=b;
}
Предполагается, что корневые элементы DOM скрывать не имеет смысла и поэтому проверки ведутся только до document.body.
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 раза
Как показывают тесты, даже при большой вложенности падение скорости невелико. Таким образом, мы получили универсальное решение, которое быстрее доступа к offsetHeight в 30–100 раз.