Что быстрее, и следовательно, что лучше использовать CSS или JavaScript. К примеру, есть группа элементов, и мне надо выделить один из них, так вот, как это лучше сделать, добавлением нового класса (и след. нового стиля) или изменить его свойства с помощью JavaScript? Речь идет не о чистом JavaScript, но для него вопрос тоже актуален, а об GWT.
4 ответа
Чистый 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
.
-
А не могли бы привести реальную статистику и окружение, в котором проводился эксперимент. У меня не получились такие же цифры. 27 мая 2011 в 9:23
-
Согласен, с цифрами погорячился. i065.radikal.ru/1105/f4/1e00afe61614.gif - вот результат для 4х различных браузеров. 25-30 - это получалось в Хроме, в ФФ и Опере соотношение колебалось около 10. В ИЕ7 - где-то 1.5. Запускал скрипт в файле с минимальной html-структурой (html, head, title, style, body). Что-то еще?– ling27 мая 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.– yozh27 мая 2011 в 11:50
-
3Дело тут, кстати, вообще не в скорости. На мой взгляд, сделать это классами - <em>правильно</em>. "Что быстрее, и следовательно, что лучше" - вряд ли это так, если вы не разрабатываете, например, код для научных расчетов. Вам же поддерживать его - сначала напишите красиво и правильно, а потом уже оптимизируйте. Очень высока вероятность, что проблемы с производительностью будут совсем в другом месте.– yozh27 мая 2011 в 12:02
Провел второй тест. Результаты в Хроме опустились до 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>
Выделение одного элемента из группы - это изменение его свойств относительно базовых свойств. Это прямая работа CSS по его философии в WEB
Три столпа:
- HTML для данных, разметки и каркаса верстки
- CSS для задания визуальных свойств и параметров отображения/поведения каркаса
- JavaScript для динамики, взаимодействия с окружением и программных задач
В вашем случае:
- Выделение элементов это изменение его отображения, эту часть надо делать добавление класса CSS
- Само назначение класса выделения может быть сделано через CSS (:hover на самом элементе или на родителе, если это возможно), либо через JavaScript по более сложным условиям (клик по-другому элементу, перемотка ползунка, ввод суммы на форме и так далее)
По поводу быстродействия - вы можете провести 1000 и 1 тест для каждого варианта. Но это лишнее. Старайтесь делать задачу "правильно" с точки зрения философии разработки или принятой методологии. Оптимизация - это дело разработчиков браузеров и интерпретаторов. Кстати, оптимизировать они будут только те варианты поведения разработчиков, которые приняты опять же в большинстве случаев
Главное, не парсите CSS-файл с помощью JS и не назначайте каждое свойство CSS каждому элементу DOM. Да, утрирую. Но ведь это возможно сделать. Но вы же не будете замерять время работы этого ужаса? Потому что так не принято делать
Когда элемент один то быстрее добавить ему другой класс из таблиц стилей, а когда нужно изменить много элементов, то лучше изменить правило для этого класса в таблице стилей.
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;
}