Скорость CSS
Это всего лишь вопрос, который поможет мне лучше понять CSS.
Допустим, у нас есть миллион строк этого.
<div class="first">
<div class="second">
<span class="third">Hello World</span>
</div>
</div>
Какой был бы самый быстрый способ изменить шрифт Hello World на красный?
.third { color: red; }
div.third { color: red; }
div.second div.third { color: red; }
div.first div.second div.third { color: red; }
Кроме того, что, если в теге в середине был уникальный идентификатор "foo". Какой из вышеперечисленных методов CSS был бы самым быстрым.
Я знаю, почему эти методы используются и т.д., я просто пытаюсь лучше понять технику рендеринга браузеров, и я понятия не имею, как сделать тест, который раз это.
UPDATE:
Хороший ответ Гумбо.
По внешнему виду, это было бы быстрее на регулярном сайте, чтобы сделать полное определение тега. Поскольку он находит родителей и сужает поиск каждого найденного родителя.
Это может быть плохо в том смысле, что у вас будет довольно большой CSS файл.
Ответы
Ответ 1
Две вещи, которые нужно запомнить:
-
Это зависит от механизма парсера/рендеринга CSS: т.е. он зависит от браузера и браузера.
-
CSS действительно, действительно, очень быстро, даже в этом случае медленнее наблюдаемый человек не должен замечать
В общем, самые простые вещи - самые быстрые (как хорошо иллюстрирует Gumbo), но поскольку мы уже находимся в такой быстрой среде, не думайте, что вы должны пожертвовать ясностью и подходящим охватом (низкая специфика - это сделать все общедоступным из). Просто избегайте *
везде, где вы можете:)
Ответ 2
Согласно Центр разработчиков Mozilla, наиболее эффективным селектором для этого случая будет просто .third
Фактически, они заявляют там, явно: "Не квалифицируйте Правила класса с именами тегов". В общем, для максимальной эффективности используйте простейший селектор, который соответствует. Вот почему .third
бьет span.third
бьет .second span.third
и т.д.
Я не могу сказать, что такое заключение Gumbo, но, по-видимому, Олафур делает вывод из этого, что использование большего количества элементов в селекторе делает анализ CSS более эффективным, когда на самом деле это просто наоборот ( предполагая, что другие синтаксические механизмы CSS работают аналогично Mozilla's.)
Ответ 3
Вы должны понимать, как обрабатываются селекторы:
-
.third
: получить каждый элемент и проверить имя класса third
,
-
div.third
: получить каждый элемент DIV
и проверить имя класса third
,
-
div.second div.third
: получить каждый элемент DIV
, проверить имя класса second
, пропустить их и найти каждый decendant DIV
и проверить имя класса third
-
div.first div.second div.third
: получить каждый элемент DIV
, проверить имя класса first
, пропустить их и найти каждый декомпозитный элемент DIV
, проверить имя класса second
, пропустите их и, наконец, проверьте имя класса third
.
Изменить. Я должен признать, что описанная выше процедура была бы наивным подходом и обычно неэффективна. Фактически, есть реализации, которые идут сверху вниз сверху вниз:
-
div.first div.second div.third
: получить каждый элемент DIV
, проверить имя класса third
, получить первый предка DIV
, у которого есть имя класса second
, получить первый DIV
, который имеет имя класса first
.
Ответ 4
Я бы сказал, это зависит от браузера. Ничто не сравнится с экспериментом, в этом случае, вероятно, будет работать простой JavaScript.
Обновление: я хотел сделать что-то вроде этого:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CSS Speed Test</title>
<style type="text/css">
.first { color: red; }
</style>
<script type="text/javascript">
window.onload = function()
{
var container = document.getElementById("container");
var totalTime = 0;
var passes = 100;
for (var p=1; p<=passes; p++)
{
var startTime = new Date();
for (var i=0; i<1000; i++)
{
var outerDiv = document.createElement("div");
var innerDiv = document.createElement("div");
var span = document.createElement("span");
outerDiv.className = "first";
innerDiv.className = "second";
span.appendChild(document.createTextNode("Hello, world!"));
outerDiv.appendChild(innerDiv);
innerDiv.appendChild(span);
container.appendChild(outerDiv);
}
var endTime = new Date();
totalTime += (endTime - startTime);
}
alert("Average time: " + totalTime/passes);
}
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
... но разницы во времени, вызванные различными селекторами, кажутся слишком маленькими для измерения, так же, как сказано в annakata.