Читать «Разгони свой сайт» онлайн - страница 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

Таблица 6.4. Резульаты выполнения функции getStyle. Времена приведены в миллисекундах

Во-первых, для 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 раза

Таблица 6.5. Резульаты выполнения функции isHidden. Времена приведены в миллисекундах

Как показывают тесты, даже при большой вложенности падение скорости невелико. Таким образом, мы получили универсальное решение, которое быстрее доступа к offsetHeight в 30–100 раз.