2009-02-11 18 views
16

To tylko pytanie, które pomoże mi lepiej zrozumieć renderowanie CSS.Prędkość CSS

Powiedzmy, że mamy milion linii tego.

<div class="first"> 
    <div class="second"> 
     <span class="third">Hello World</span> 
    </div> 
</div> 

Jaki byłby najszybszy sposób na zmianę czcionki Hello World na czerwony?

.third { color: red; } 
div.third { color: red; } 
div.second div.third { color: red; } 
div.first div.second div.third { color: red; } 

Co się też dzieje, jeśli na środku tagu był unikalny identyfikator "foo". Która z powyższych metod CSS byłaby najszybsza.

Wiem, dlaczego te metody są używane itp., Po prostu próbuję uchwycić lepszą technikę renderowania przeglądarek i nie mam pojęcia, jak zrobić test, który to razy.

AKTUALIZACJA: Dobra odpowiedź Gumbo. Z tego wyglądu będzie szybciej w zwykłej witrynie, aby wykonać pełną definicję tagu. Ponieważ znajduje rodziców i zawęża wyszukiwanie wszystkich znalezionych rodziców.

To może być złe w tym sensie, że masz dość duży plik CSS.

Odpowiedz

13

dwie rzeczy do zapamiętania:

  • To będzie zależeć od CSS parser/silnika renderowania: to znaczy, że waha się od przeglądarki do przeglądarki.

  • CSS jest naprawdę, naprawdę, naprawdę szybko i tak, nawet na to najwolniejsze ludzka obserwacja nie powinni zauważyć

w ogóle najprostsze rzeczy są najszybciej (jak ładnie ilustruje Gumbo) ale ponieważ jesteśmy już w tak szybkim środowisku, nie myśl, że powinieneś poświęcić jasność i właściwe określanie zakresu (niska specyficzność jest jak upublicznianie wszystkiego). Wystarczy unikać * gdzie możesz :)

7

Trzeba zrozumieć, jak selektory są przetwarzane:

  • .third: dostać każdy element i sprawdzić nazwy klasy third,
  • div.third: dostać każdy DIV element i sprawdzić nazwa klasy: third,
  • div.second div.third: pobierz co DIV elementem, należy sprawdzić nazwę klasy second, prowadzonym przez nich i znaleźć każdy decendant DIV element i sprawdzić nazwy klasy third,
  • div.first div.second div.third: dostać każdy DIV elementu, należy sprawdzić nazwę klasy first, prowadzony przez nich i znajdź każdy podwieszony element DIV, sprawdź nazwę klasy second, przeprowadź przez nie i sprawdź nazwę klasy third.

Edit muszę przyznać, że procedura powyżej byłoby naiwne podejście i generalnie nie jest wydajny. W rzeczywistości istnieją implementacje, które idą od dołu do góry, a nie od góry do dołu:

  • div.first div.second div.third: dostać każdy DIV elementu, należy sprawdzić nazwę klasy third, zdobyć pierwszy DIV przodka, który ma nazwę klasy second, pobierz pierwszy przodek DIV o nazwie klasy first.
+0

Istnieją nawet silniki, które przeszukują dom, a nie CSS - czy ten element pasuje do tego selektora? Nie? A co powiesz o tym? Istnieje również cały styl logiki skrótów. – annakata

+2

Prędkość strony Google ma bardzo przydatne informacje: http://code.google.com/speed/page-speed/docs/rendering.html - krótko mówiąc, używają tylko klas i identyfikatorów na własną rękę, bez tagów kwalifikujących , jest najszybszy. – DisgruntledGoat

0

Powiedziałbym, że to zależy od przeglądarki. Nic nie przebije eksperymentu, w tym przypadku prawdopodobnie zrobiłby to prosty JavaScript.

Aktualizacja: chciałem zrobić coś takiego:

<!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> 

... ale różnice czasowe wynikające z różnych selektorów wydają się być zbyt mała, aby zmierzyć, jak annakata powiedział.

+0

Och, oczywiście miałem na celu * czas * różnych selektorów używających JavaScript. – zoul

+0

oic - ma sens teraz :) – annakata

8

Według Mozilla Developer Center, najbardziej wydajny wybierak w tym przypadku byłoby po prostu .third

W rzeczywistości, stwierdzają oni tam wyraźnie: „Nie kwalifikuje przepisami klasowymi z tagiem nazwy". Zasadniczo, dla największej wydajności, użyj najprostszego selektora, który pasuje. Dlatego .third uderzeń span.third bije .second span.third itp

Nie mogę powiedzieć, co konkluzja Gumbo jest miało być, ale Ólafur wydaje się rysunek zawarcia z nim, że użycie więcej rzeczy w selektorze czyni CSS analizowania bardziej wydajne , gdy w rzeczywistości jest wręcz przeciwnie (zakładając, że inne mechanizmy analizujące CSS działają podobnie do Mozilli).

+0

Dobra odpowiedź tam. –