3

Что быстрее, и следовательно, что лучше использовать CSS или JavaScript. К примеру, есть группа элементов, и мне надо выделить один из них, так вот, как это лучше сделать, добавлением нового класса (и след. нового стиля) или изменить его свойства с помощью JavaScript? Речь идет не о чистом JavaScript, но для него вопрос тоже актуален, а об GWT.

4 ответа 4

5

Чистый js:

document.write('<br>');
var s = performance.now();
for (var i = 0; i < 100000; ++i)
  document.body.style.border = '1px red solid';
document.write(performance.now() - s);

document.write('<br>');
s = performance.now();
for (var i = 0; i < 100000; ++i)
  document.body.classList.add('redBorder');
  document.body.classList.remove('redBorder');
document.write(performance.now() - s);
.redBorder {
  border: 1px red solid;
}

Добавление класса происходит быстрее (у меня - раз в 25-30), тем более, что можно сначала проверить наличие класса. Если же надо выделить элемент при наведении, то можно обойтись и css-псевдоклассом :hover.

4
  • А не могли бы привести реальную статистику и окружение, в котором проводился эксперимент. У меня не получились такие же цифры. 27 мая 2011 в 9:23
  • Согласен, с цифрами погорячился. i065.radikal.ru/1105/f4/1e00afe61614.gif - вот результат для 4х различных браузеров. 25-30 - это получалось в Хроме, в ФФ и Опере соотношение колебалось около 10. В ИЕ7 - где-то 1.5. Запускал скрипт в файле с минимальной html-структурой (html, head, title, style, body). Что-то еще?
    – ling
    27 мая 2011 в 10:16
  • @ling у вас в случае с CSS классами условие выполняется лишь один раз. Если добавить document.body.className = document.body.className.substr(0, document.body.className.length - 10); и, соответственно, document.body.style.border = ''; разница будет не так заметна - ~1.3 Firefox/Linux. С другой стороны, небольшую надбавку вносит создание RegExp объекта, его кеширование снимает на моей системе ~80 мс. @RomZ Еще один момент - CSS классы дадут гораздо больший прирост, если свойств несколько. Время применения CSS класса увеличится, конечно, но это всего ~7% по сравнение с ~100% для JS.
    – yozh
    27 мая 2011 в 11:50
  • 3
    Дело тут, кстати, вообще не в скорости. На мой взгляд, сделать это классами - <em>правильно</em>. "Что быстрее, и следовательно, что лучше" - вряд ли это так, если вы не разрабатываете, например, код для научных расчетов. Вам же поддерживать его - сначала напишите красиво и правильно, а потом уже оптимизируйте. Очень высока вероятность, что проблемы с производительностью будут совсем в другом месте.
    – yozh
    27 мая 2011 в 12:02
2

Провел второй тест. Результаты в Хроме опустились до 10 к 1. В остальных браузерах мало что поменялось. Примечание: выполнять добавление обводки надо каждым способом поодиночке, иначе получаются неправильные результаты.

<!doctype html>
<html>
<head>
<title></title>
<style type="text/css">
.redBorder{border:1px red solid}
</style>
</head>
<body>

<script>
for(var i = 0; i < 5000; ++i)
    document.body.appendChild(document.createElement('span'));

var sp = document.getElementsByTagName('span');
var str = '';

//*
str += '\n';
var s = (new Date()).getTime();
for(var i = 0; i < sp.length; ++i)
    sp[i].style.border = '1px red solid';
str += (new Date()).getTime() - s;
/**/

/*
str += '\n';
s = (new Date()).getTime();
for(var i = 0; i < sp.length; ++i)
    sp[i].className += ' redBorder';
str += (new Date()).getTime() - s;
/**/

document.write(str);
</script>

</body>
</html>
3
  • Firefox/Linux - ~2x
    – yozh
    27 мая 2011 в 12:19
  • Все равно добавлять класс - быстрее будет).
    – ling
    27 мая 2011 в 13:51
  • да я ж не спорю, это так, для полноты
    – yozh
    27 мая 2011 в 14:05
0

Выделение одного элемента из группы - это изменение его свойств относительно базовых свойств. Это прямая работа CSS по его философии в WEB

Три столпа:

  • HTML для данных, разметки и каркаса верстки
  • CSS для задания визуальных свойств и параметров отображения/поведения каркаса
  • JavaScript для динамики, взаимодействия с окружением и программных задач

В вашем случае:

  • Выделение элементов это изменение его отображения, эту часть надо делать добавление класса CSS
  • Само назначение класса выделения может быть сделано через CSS (:hover на самом элементе или на родителе, если это возможно), либо через JavaScript по более сложным условиям (клик по-другому элементу, перемотка ползунка, ввод суммы на форме и так далее)

По поводу быстродействия - вы можете провести 1000 и 1 тест для каждого варианта. Но это лишнее. Старайтесь делать задачу "правильно" с точки зрения философии разработки или принятой методологии. Оптимизация - это дело разработчиков браузеров и интерпретаторов. Кстати, оптимизировать они будут только те варианты поведения разработчиков, которые приняты опять же в большинстве случаев

Главное, не парсите CSS-файл с помощью JS и не назначайте каждое свойство CSS каждому элементу DOM. Да, утрирую. Но ведь это возможно сделать. Но вы же не будете замерять время работы этого ужаса? Потому что так не принято делать

0

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

var sp = [];
for (var i = 0; i < 5000; ++i) {
  let s = document.body.appendChild(document.createElement('span'));
  s.className = "blueBorder";
  sp.push(s);
}

var str = '';

str += '<br/>';
s = s = performance.now();
for (var i = 0; i < sp.length; ++i)
  sp[i].className += ' redBorder';
str += (performance.now() - s);


str += '<br/>';
s = s = performance.now();
let lastIndex = document.styleSheets[0].cssRules.length;
document.styleSheets[0].insertRule(".blueBorder{border: 1px solid blue}", lastIndex);
str += (performance.now() - s);


document.write(str);
.redBorder {
  border: 1px red solid;
}

Ваш ответ

By clicking “Отправить ответ”, you agree to our terms of service and acknowledge you have read our privacy policy.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками или задайте свой вопрос.