html - wenn - Warum stimmen Browser CSS-Selektoren von rechts nach links ab?




css wenn dann (2)

CSS-Selektoren werden von Browser-Engines von rechts nach links abgeglichen. So finden sie zuerst die Kinder und überprüfen dann ihre Eltern, um zu sehen, ob sie mit den übrigen Teilen der Regel übereinstimmen.

  1. Warum ist das?
  2. Ist es nur, weil die Spezifikation sagt?
  3. Beeinflusst es das eventuelle Layout, wenn es von links nach rechts ausgewertet wurde?

Am einfachsten wäre es für mich, die Selektoren mit der geringsten Anzahl an 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 - zB kann es nur einen Bereich auf der Seite geben, also gehe direkt zu diesem Knoten mit irgendeiner Regel, die einen Bereich referenziert.

Hier sind einige Links, die meine Behauptungen bestätigen

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

Es klingt so, als würde es so gemacht, um nicht alle Kinder eines Elternteils (die viele sein könnten) zu betrachten, statt alle Eltern eines Kindes, das eins sein muss. Selbst wenn das DOM tief ist, würde es nur einen Knoten pro Ebene und nicht mehrere im RTL-Abgleich betrachten. Ist es einfacher / schneller, die CSS-Selektoren LTR oder RTL zu bewerten?


Das Parsen von rechts nach links, auch Bottom-up-Parsing genannt, ist für den Browser tatsächlich effizient.

Folgendes berücksichtigen:

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

Der Browser #menu zuerst nach a , dann nach li , dann nach ul und dann nach #menu .

Dies liegt daran, dass der Browser die Seite nur scannt, um das aktuelle Element / den Knoten und alle vorherigen Knoten / Elemente, die es gescannt hat, zu betrachten.

Zu beachten ist, dass der Browser die Verarbeitung sofort startet, wenn er ein vollständiges Tag / Knoten bekommt und nicht auf die ganze Seite warten muss, außer wenn er ein Skript findet. In diesem Fall hält er die Ausführung des Skripts vorübergehend an geht weiter.

Umgekehrt ist es ineffizient, weil der Browser das Element gefunden hat, das bei der ersten Prüfung gescannt wurde, und dann gezwungen war, das Dokument weiter nach allen zusätzlichen Selektoren zu durchsuchen. Dazu muss der Browser den gesamten HTML-Code haben und eventuell die gesamte Seite scannen, bevor das css painting beginnt.

Dies steht im Gegensatz dazu, wie die meisten Bibliotheken dom analysieren. Dort wird das dom erstellt und es muss nicht die gesamte Seite gescannt werden, sondern nur das erste Element gefunden werden und dann die anderen darin suchen.


Denken Sie daran, dass wenn ein Browser Selektor-Matching vornimmt, er ein Element (das, für das er den Stil bestimmen will) und all Ihre Regeln und seine Selektoren hat und es herausfinden muss, welche Regeln zu dem Element passen. Das unterscheidet sich von der üblichen jQuery-Sache, wo Sie nur einen Selektor haben und Sie müssen alle Elemente finden, die mit diesem Selektor übereinstimmen.

Wenn Sie nur einen Selektor und nur ein Element zum Vergleich mit diesem Selektor hatten, ist in einigen Fällen von links nach rechts sinnvoller. Aber das ist definitiv nicht die Situation des Browsers. Der Browser versucht, Gmail oder was auch immer zu rendern und hat die eine <span> es zu stylen versucht, und die über 10.000 Regeln, die Gmail in sein Stylesheet schreibt (ich mache diese Nummer nicht).

Insbesondere in der Situation, in der der Browser die meisten ausgewählten Selektoren betrachtet, stimmen sie nicht mit dem fraglichen Element überein. Das Problem besteht also darin, zu entscheiden, dass ein Selektor nicht so schnell wie möglich zusammenpasst; Wenn das in den Fällen, die mit Ihnen übereinstimmen, etwas mehr Arbeit erfordert, gewinnen Sie trotzdem aufgrund der gesamten Arbeit, die Sie in den Fällen speichern, die nicht übereinstimmen.

Wenn Sie damit beginnen, nur den rechten Teil des Selektors mit Ihrem Element abzugleichen, ist es wahrscheinlich, dass es nicht übereinstimmt und Sie fertig sind. Wenn es passt, müssen Sie mehr Arbeit leisten, aber nur proportional zu Ihrer Baumtiefe, die in den meisten Fällen nicht so groß ist.

Auf der anderen Seite, wenn Sie mit dem linken Teil des Selektors beginnen ... Womit stimmen Sie überein? Sie müssen mit dem DOM beginnen und nach Knoten suchen, die zu ihm passen. Nur zu entdecken, dass es nichts gibt, was mit dem linken Teil zusammenhängt, könnte eine Weile dauern.

Die Browser stimmen also von rechts überein; es gibt einen offensichtlichen Ausgangspunkt und lässt Sie die meisten Kandidatenselektoren sehr schnell loswerden. Sie können einige Daten unter http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (obwohl die Schreibweise verwirrend ist), aber das Ergebnis ist insbesondere für Google Mail Vor zwei Jahren konnten Sie bei 70% der (Regel-, Element-) Paare entscheiden, dass die Regel nicht übereinstimmt, nachdem Sie nur die Tags / Klassen / ID-Teile des ganz rechts stehenden Selektors für die Regel überprüft haben. Die entsprechende Anzahl für Mozillas Pagenoad-Performance-Tests betrug 72%. Es ist also wirklich einen Versuch wert, diese 2/3 aller Regeln so schnell wie möglich loszuwerden und sich dann nur darum zu kümmern, das verbleibende 1/3 zu erreichen.

Beachten Sie auch, dass es andere Optimierungen gibt, die Browser bereits durchführen, um zu vermeiden, dass Sie sogar versuchen, Regeln zu finden, die definitiv nicht übereinstimmen. Wenn beispielsweise der Selektor ganz rechts eine ID hat und diese ID nicht mit der ID des Elements übereinstimmt, wird in Gecko kein Versuch unternommen, diesen Selektor mit diesem Element abzugleichen: die Menge der "Selektoren mit IDs", die versucht werden kommt aus einer Hash-Suche nach der ID des Elements. Das sind also 70% der Regeln, die eine ziemlich gute Chance auf Übereinstimmung haben, die immer noch nicht übereinstimmen, wenn man nur das Tag / class / id des Selektors ganz rechts betrachtet.





css-selectors