Los selectores de CSS coinciden con los motores del navegador de derecha a izquierda. Entonces, primero encuentran a los niños y luego verifican a sus padres para ver si coinciden con el resto de las partes de la regla.
- ¿Por qué es esto?
- ¿Es solo porque la especificación dice?
- ¿Afecta el diseño final si se evaluó de izquierda a derecha?
Para mí, la forma más sencilla de hacerlo sería utilizar los selectores con el menor número de elementos. Entonces, los ID primero (ya que solo deberían devolver 1 elemento). Entonces, tal vez clases o un elemento que tenga el menor número de nodos, por ejemplo, puede haber solo un intervalo en la página, así que vaya directamente a ese nodo con cualquier regla que haga referencia a un intervalo.
Aquí hay algunos enlaces que respaldan mis afirmaciones
- http://code.google.com/speed/page-speed/docs/rendering.html
- https://developer.mozilla.org/en/Writing_Efficient_CSS
Parece que se hace de esta manera para evitar tener que mirar a todos los hijos de los padres (que podrían ser muchos) en lugar de a todos los padres de un niño que debe ser uno. Incluso si el DOM es profundo, solo vería un nodo por nivel en lugar de múltiples en la coincidencia RTL. ¿Es más fácil / rápido evaluar los selectores CSS LTR o RTL?
fuente
#foo
selector necesitaría coincidir con todos esos nodos. jQuery tiene la opción de decir que $ ("# foo") siempre devolverá solo un elemento, porque están definiendo su propia API con sus propias reglas. Pero los navegadores necesitan implementar CSS, y CSS dice que haga coincidir todo en el documento con la ID dada.querySelectorAll
). En otros casos, se usa Sizzle. Sizzle no coincide con múltiples ID pero QSA sí (AYK). La ruta tomada depende del selector, el contexto y el navegador y su versión. La API de consulta de jQuery utiliza lo que he denominado "Native First, Dual Approach". Escribí un artículo sobre eso, pero está abajo. Aunque puede encontrar aquí: fortybelow.ca/hosted/dhtmlkitchen/JavaScript-Query-Engines.htmlRespuestas:
Tenga en cuenta que cuando un navegador está haciendo una selección de selector, tiene un elemento (el que está tratando de determinar el estilo) y todas sus reglas y sus selectores y necesita encontrar qué reglas coinciden con el elemento. Esto es diferente de lo habitual de jQuery, por ejemplo, donde solo tiene un selector y necesita encontrar todos los elementos que coincidan con ese selector.
Si solo tenía un selector y solo un elemento para comparar con ese selector, entonces de izquierda a derecha tiene más sentido en algunos casos. Pero definitivamente esa no es la situación del navegador. El navegador está tratando de representar Gmail o lo que sea y tiene el
<span>
que está tratando de diseñar y las más de 10,000 reglas que Gmail pone en su hoja de estilo (no estoy inventando ese número).En particular, en la situación en que el navegador está mirando la mayoría de los selectores que está considerando no coinciden con el elemento en cuestión. Entonces, el problema se convierte en decidir que un selector no coincide lo más rápido posible; si eso requiere un poco de trabajo extra en los casos que coinciden, aún ganas debido a todo el trabajo que ahorras en los casos que no coinciden.
Si comienza haciendo coincidir la parte más a la derecha del selector con su elemento, entonces es probable que no coincida y ya está. Si coincide, tiene que hacer más trabajo, pero solo proporcional a la profundidad de su árbol, que no es tan grande en la mayoría de los casos.
Por otro lado, si comienza haciendo coincidir la parte más a la izquierda del selector ... ¿con qué lo hace coincidir? Debe comenzar a recorrer el DOM, buscando nodos que puedan coincidir con él. Descubrir que no hay nada que coincida con la parte izquierda puede llevar un tiempo.
Entonces los navegadores coinciden desde la derecha; proporciona un punto de partida obvio y le permite deshacerse de la mayoría de los selectores candidatos muy rápidamente. Puede ver algunos datos en http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (aunque la notación es confusa), pero el resultado es el de Gmail en particular hace dos años, para el 70% de los pares (regla, elemento), podría decidir que la regla no coincide después de solo examinar las partes de etiqueta / clase / id del selector más a la derecha de la regla. El número correspondiente para el conjunto de pruebas de rendimiento de carga de página de Mozilla fue del 72%. Por lo tanto, realmente vale la pena tratar de deshacerse de esos 2/3 de todas las reglas lo más rápido posible y luego solo preocuparse por igualar el 1/3 restante.
Tenga en cuenta también que hay otros optimizadores que los navegadores ya hacen para evitar incluso intentar igualar reglas que definitivamente no coincidirán. Por ejemplo, si el selector más a la derecha tiene una identificación y esa identificación no coincide con la identificación del elemento, entonces no habrá ningún intento de hacer coincidir ese selector con ese elemento en Gecko: el conjunto de "selectores con ID" que se intentan proviene de una búsqueda de tabla hash en la ID del elemento. Entonces, este es el 70% de las reglas que tienen una muy buena posibilidad de coincidencia que aún no coinciden después de considerar solo la etiqueta / clase / id del selector más a la derecha.
fuente
El análisis de derecha a izquierda, también llamado análisis de abajo hacia arriba, es realmente eficiente para el navegador.
Considera lo siguiente:
El navegador primero busca
a
, luegoli
, luegoul
y luego#menu
.Esto se debe a que mientras el navegador escanea la página, solo necesita mirar el elemento / nodo actual y todos los nodos / elementos anteriores que ha escaneado.
Lo que hay que tener en cuenta es que el navegador comienza a procesar el momento en que obtiene una etiqueta / nodo completo y no necesita tener que esperar toda la página, excepto cuando encuentra un script, en cuyo caso se detiene temporalmente y completa la ejecución del script y luego sigue adelante
Si lo hace al revés, será ineficiente porque el navegador encontró el elemento que estaba escaneando en la primera verificación, pero luego se vio obligado a continuar buscando en el documento todos los selectores adicionales. Para esto, el navegador debe tener todo el html y es posible que deba escanear toda la página antes de comenzar a pintar con CSS.
Esto es contrario a cómo la mayoría de las bibliotecas analizan dom. Allí se construye el dom y no necesita escanear toda la página, solo encuentra el primer elemento y luego sigue haciendo coincidir otros dentro de él.
fuente
Permite la conexión en cascada de lo más específico a lo menos específico. También permite un corto circuito en la aplicación. Si la regla más específica se aplica en todos los aspectos a los que se aplica la regla principal, se ignoran todas las reglas principales. Si hay otros bits en el padre, se aplican.
Si fue al revés, formateará de acuerdo con el padre y luego sobrescribirá cada vez que el niño tenga algo diferente. A la larga, esto es mucho más trabajo que ignorar los elementos en las reglas que ya se tienen en cuenta.
fuente