597 Stimmen

Warum passen die Browser CSS-Selektoren von rechts nach links an?

CSS-Selektoren werden von Browser-Engines von rechts nach links abgeglichen. Sie finden also zunächst die untergeordneten Elemente und prüfen dann, ob sie mit den übrigen Teilen der Regel übereinstimmen.

  1. Warum ist das so?
  2. Ist das nur so, weil es in der Spezifikation steht?
  3. Beeinflusst es das letztendliche Layout, wenn es von links nach rechts ausgewertet wurde?

Für mich wäre es am einfachsten, die Selektoren mit der geringsten Anzahl von Elementen zu verwenden. Also IDs zuerst (da sie nur 1 Element zurückgeben sollten). Dann vielleicht Klassen oder ein Element, das die geringste Anzahl von Knoten hat - z. B. kann es nur eine Spanne auf der Seite sein, so gehen Sie direkt zu diesem Knoten mit jeder Regel, die eine Spanne verweist.

Hier sind einige Links, die meine Behauptungen untermauern

  1. http://code.google.com/speed/page-speed/docs/rendering.html
  2. https://developer.mozilla.org/en/Writing_Efficient_CSS

Es hört sich so an, als ob dies so gemacht wird, um zu vermeiden, dass alle Kinder eines Elternteils (die viele sein könnten) betrachtet werden müssen, anstatt alle Eltern eines Kindes, die eins sein müssen. Selbst wenn das DOM tief ist, würde es nur auf einen Knoten pro Ebene statt mehrere in der RTL-Matching aussehen. Ist es einfacher/schneller, CSS-Selektoren LTR oder RTL auszuwerten?

5 Stimmen

3. Nein - egal wie man es liest, der Selektor passt immer auf dieselbe Gruppe von Elementen.

1 Stimmen

Das Parsen Weg, den Sie vorschlagen, wäre nicht wirklich wirksam, da es Zugriff auf das DOM eine Menge erfordert. Ich würde es von links nach rechts zu analysieren, und vermutlich, Selektoren wie jQuery parsen es von links nach rechts zu.

0 Stimmen

@Sime Vidas - Warum wird es dann von rechts nach links gemacht?

859voto

Boris Zbarsky Punkte 34218

Denken Sie daran, dass ein Browser beim Selektorabgleich ein Element (das, für das er den Stil zu bestimmen versucht) und alle Ihre Regeln und deren Selektoren hat, und dass er herausfinden muss, welche Regeln mit dem Element übereinstimmen. Dies unterscheidet sich von der üblichen jQuery-Sache, wo man nur einen Selektor hat und alle Elemente finden muss, die diesem Selektor entsprechen.

Hätten Sie nur einen Selektor und nur ein Element, das mit diesem Selektor verglichen werden soll, dann wäre es in manchen Fällen sinnvoller, von links nach rechts zu suchen. Aber das ist eindeutig no die Situation des Browsers. Der Browser versucht, Gmail oder was auch immer zu rendern und hat die eine <span> und die mehr als 10.000 Regeln, die Gmail in sein Stylesheet aufnimmt (ich denke mir diese Zahl nicht aus).

Insbesondere in der Situation, in der der Browser die meisten der Selektoren betrachtet, die er in Betracht zieht nicht mit dem fraglichen Element übereinstimmen. Das Problem besteht also darin, so schnell wie möglich zu entscheiden, dass ein Selektor nicht übereinstimmt. Wenn das in den Fällen, die übereinstimmen, ein wenig zusätzliche Arbeit erfordert, gewinnt man trotzdem aufgrund der Arbeit, die man in den Fällen spart, die nicht übereinstimmen.

Wenn Sie zunächst nur den ganz rechten Teil des Selektors mit Ihrem Element abgleichen, ist die Wahrscheinlichkeit groß, dass er nicht übereinstimmt und Sie sind fertig. Wenn es übereinstimmt, müssen Sie mehr Arbeit leisten, aber nur proportional zu Ihrer Baumtiefe, die in den meisten Fällen nicht so groß ist.

Andererseits, wenn Sie damit beginnen, den ganz linken Teil des Selektors abzugleichen... womit vergleichen Sie ihn dann? Sie müssen das DOM nach Knoten durchsuchen, die damit übereinstimmen könnten. Allein die Entdeckung, dass es nichts gibt, was mit dem ganz linken Teil übereinstimmt, kann eine Weile dauern.

Die Browsersuche erfolgt also von rechts; sie bietet einen offensichtlichen Ausgangspunkt und ermöglicht es Ihnen, die meisten Selektionskandidaten sehr schnell loszuwerden. Sie können einige Daten sehen unter http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (obwohl die Notation verwirrend ist), aber das Ergebnis ist, dass man insbesondere bei Google Mail vor zwei Jahren bei 70 % der (Regel, Element)-Paare entscheiden konnte, dass die Regel nicht übereinstimmt, nachdem man nur die Tag/Klasse/ID-Teile des Selektors ganz rechts für die Regel untersucht hatte. Die entsprechende Zahl für Mozilla's pageload performance test suite war 72%. Es lohnt sich also wirklich zu versuchen, diese 2/3 aller Regeln so schnell wie möglich loszuwerden und sich dann nur noch um die Übereinstimmung des verbleibenden 1/3 zu kümmern.

Beachten Sie auch, dass es andere Optimierungen gibt, die Browser bereits vornehmen, um zu vermeiden, dass sie überhaupt versuchen, Regeln zu erfüllen, die definitiv nicht erfüllt werden können. Wenn zum Beispiel der Selektor ganz rechts eine id hat und diese id nicht mit der id des Elements übereinstimmt, dann wird in Gecko überhaupt nicht versucht, diesen Selektor mit dem Element abzugleichen: Die Menge der "Selektoren mit IDs", die versucht werden, stammt aus einem Hash-Table-Lookup auf die ID des Elements. Dies sind also 70% der Regeln, die eine ziemlich gute Chance haben, mit dem immer noch nicht übereinstimmen, nachdem nur der Tag/die Klasse/die ID des Selektors ganz rechts berücksichtigt wurde.

5 Stimmen

Als kleiner Bonus ist es sogar im Englischen sinnvoller, es als RTL zu lesen als als LTR. Ein Beispiel: stackoverflow.com/questions/3851635/css-combinator-precedence/

8 Stimmen

Beachten Sie, dass der RTL-Abgleich nur für Kombinatoren . Es wird nicht bis auf die Ebene des einfachen Selektors heruntergebrochen. Das heißt, ein Browser nimmt die ganz rechte Mehrfachselektor o Folge von einfachen Selektoren und versucht, es atomar abzugleichen. Wenn es eine Übereinstimmung gibt, folgt es dem Kombinator nach links zum nächster Verbundselektor und prüft das Element an dieser Position usw. Es gibt keinen Beweis dafür, dass ein Browser jeden Teil eines zusammengesetzten Selektors RTL liest; tatsächlich zeigt der letzte Absatz genau das Gegenteil (id-Checks kommen immer zuerst).

5 Stimmen

Zu dem Zeitpunkt, an dem Sie Selektoren abgleichen, kommen zumindest in Gecko der Tagname und der Namespace zuerst. Die id (ebenso wie der Tagname und die Klassennamen) wird in einem Vorfilterungsschritt berücksichtigt, der die meisten Regeln eliminiert, ohne wirklich zu versuchen, die Selektoren abzugleichen.

38voto

aWebDeveloper Punkte 33447

Rechts-nach-links-Parsing, auch bezeichnet als Bottom-Up-Parsing ist tatsächlich effizient für den Browser.

Bedenken Sie Folgendes:

#menu ul li a { color: #00f; }

Der Browser prüft zunächst auf a entonces li entonces ul und dann #menu .

Das liegt daran, dass der Browser beim Scannen der Seite nur das aktuelle Element/Knoten und alle vorherigen Knoten/Elemente, die er gescannt hat, betrachten muss.

Es ist zu beachten, dass die der Browser beginnt mit der Verarbeitung, sobald er einen vollständigen Tag/Knoten erhält und muss nicht die ganze Seite abwarten, es sei denn, es wird ein Skript gefunden. In diesem Fall wird die Ausführung des Skripts vorübergehend angehalten und abgeschlossen und dann fortgesetzt.

Andersherum ist es ineffizient, weil der Browser das Element, das er bei der ersten Überprüfung gefunden hat, dann aber gezwungen war, das Dokument weiter nach allen zusätzlichen Selektoren zu durchsuchen. Hierfür benötigt der Browser die gesamte HTML-Datei und muss möglicherweise die gesamte Seite scannen, bevor er mit der CSS-Malerei beginnt.

Dies steht im Gegensatz zu der Art und Weise, wie die meisten Libs den Dom analysieren. Dort wird das dom konstruiert und es muss nicht die gesamte Seite scannen, sondern nur das erste Element finden und dann mit den anderen Elementen darin fortfahren.

20voto

Gregory A Beamer Punkte 16670

Sie ermöglicht eine Kaskadierung vom Spezifischen zum weniger Spezifischen. Sie ermöglicht auch einen Kurzschluss in der Anwendung. Wenn die spezifischere Regel für alle Aspekte gilt, für die die übergeordnete Regel gilt, werden alle übergeordneten Regeln ignoriert. Sind in der übergeordneten Regel andere Bits vorhanden, werden diese angewendet.

In umgekehrter Richtung würden Sie nach dem Elternteil formatieren und dann jedes Mal überschreiben, wenn das Kind etwas anderes hat. Auf lange Sicht ist das viel mehr Arbeit als das Ignorieren von Elementen in Regeln, die bereits berücksichtigt wurden.

11 Stimmen

Das ist ein anderes Thema. Sie führen die Kaskadierung durch, indem Sie die Regeln nach ihrer Spezifität sortieren und sie dann in der Reihenfolge der Spezifität abgleichen. Aber die Frage hier ist, warum für eine bestimmte Regel Sie seine Selektoren in einer bestimmten Weise entsprechen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X