2012-06-27 20 views
6

Teniendo en cuenta los detalles del procesamiento de CSS, más notablemente RTL matching y selector efficiency, ¿cómo se deben escribir los selectores simplemente desde la perspectiva del rendimiento del motor?Elección de selectores eficientes basados ​​en la complejidad computacional

Esto debería cubrir aspectos generales e incluir el uso o la evitación de pseudo-clases, pseudo-elementos y selectores de relaciones.

+1

Una buena pregunta, pero recuerda siempre: el rendimiento no lo es todo hasta que es lo único de lo que hay que preocuparse. Solo comience a preocuparse por el rendimiento si está seguro de que necesita ahorrar tanto como sea posible y su diseño lo permita. – BoltClock

+2

El "Selector de Selector de CSS" en las Herramientas para Desarrolladores de Chrome es útil si desea ... perfilar sus selectores de CSS. – thirtydot

Respuesta

6

En tiempo de ejecución, un documento HTML se analiza en un árbol DOM que contiene N elementos con una profundidad promedio de D. También hay un total de S reglas de CSS en las hojas de estilo aplicadas.

  1. estilos Elementos se aplican de forma individual significa existe una relación directa entre N y la complejidad global. Vale la pena señalar que esto puede ser compensado por la lógica del navegador, como el almacenamiento en caché de referencia y los estilos de reciclaje de elementos idénticos. Por ejemplo, los siguientes elementos de la lista tendrán las mismas propiedades de CSS aplicados (suponiendo que no hay pseudo-clases tales como :nth-child se aplican):

    <ul class="sample"> 
        <li>one</li> 
        <li>two</li> 
        <li>three</li> 
    </ul> 
    
  2. selectores se hacían juego de derecha a izquierda para la elegibilidad regla individual - es decir, si la tecla más a la derecha no coincide con un elemento en particular, no es necesario procesar más el selector y se descarta. Esto significa que la tecla de la derecha debe coincidir con el menor número posible de elementos. A continuación, el descriptor p coincidirá más elementos incluidos los párrafos fuera del contenedor de destino (que, por supuesto, no tendrá que aplicar la regla, pero se siguen produciendo más iteraciones de la elegibilidad de cheques para que el selector particular):

    .custom-container p {} 
    .container .custom-paragraph {} 
    
  3. Selectores de relación: selector de descendientes requiere para hasta D elementos que se iterarán sobre. Por ejemplo, la coincidencia exitosa de .container .content solo puede requerir un paso si los elementos están en una relación padre-hijo, pero el árbol DOM deberá atravesar todo el camino hasta html antes de que un elemento pueda confirmarse una discrepancia y la regla se descarte de manera segura . Esto también se aplica a los selectores de descendientes encadenados, con algunas asignaciones.

    Por otro lado, un selector de > niño, un selector adyacente + o :first-child todavía requieren un elemento adicional para ser evaluados, pero sólo tienen una profundidad implícita de uno y nunca se necesita más recorrido del árbol.

  4. El behavior definition de pseudo-elementos tales como :before y :after implica que no son parte del paradigma RTL. La lógica es la suposición de que no hay pseudo elemento per se hasta que una regla indique que se inserte antes o después del contenido de un elemento (lo que a su vez requiere manipulación DOM adicional pero no se requiere un cálculo adicional para coincidir con el selector).

  5. No pude encontrar ninguna información sobre las pseudo-clases como :nth-child() o :disabled. Verificar un estado de elemento requeriría un cálculo adicional, pero desde la perspectiva de análisis de reglas solo tendría sentido que se excluyeran del procesamiento de RTL.

Teniendo en cuenta estas relaciones, la complejidad computacional O(N*D*S) debería reducirse principalmente reduciendo al mínimo la profundidad de selectores CSS y abordar el punto 2 anterior. Esto dará lugar a mejoras cuantificables más fuertes en comparación con la minimización del número de reglas de CSS o elementos HTML solo^

Los selectores específicos de nivel bajo, preferiblemente de un nivel, se procesan más rápido. Esto es llevado a un nivel completamente nuevo de Google (mediante programación, no a mano!), Por ejemplo, rara vez hay un selector de tres llaves y la mayoría de las normas en los resultados de búsqueda parezca

#gb {} 
#gbz, #gbg {} 
#gbz {} 
#gbg {} 
#gbs {} 
.gbto #gbs {} 
#gbx3, #gbx4 {} 
#gbx3 {} 
#gbx4 {} 
/*...*/ 

^- mientras que esto es cierto desde un punto de vista de rendimiento motor de renderizado, siempre hay factores adicionales tales como el tráfico de arriba y DOM análisis sintáctico etc.

Fuentes: 12345

+1

En Selectores, todos los pseudoelementos (no solo ':: before 'y' :: after') están sujetos a la misma regla que solo se pueden aplicar al tema de un selector y solo se evalúan una vez completada la selección del selector - http://www.w3.org/TR/selectors/#pseudo-elements De CSS1 a CSS3, este es siempre el selector de clave; Sin embargo, en CSS4 esto puede cambiar. – BoltClock

+1

El análisis RTL es un detalle de la implementación y puede variar de un motor a otro, pero el concepto general de comenzar en el selector de teclas y trabajar hacia atrás se acordó entre los proveedores. Los selectores simples en cada selector compuesto primero se evalúan como algo que solo el código fuente puede responder ... más sobre eso [aquí] (http://stackoverflow.com/questions/10106345/css-selector-engine-clarification/ 10108700 # 10108700). – BoltClock

+0

@BoltClock: buen punto; Estaría dispuesto a especular que el selector de padres CSS4 será efectivamente una pseudoclase con una condición * has-children *; de lo contrario, podría haber una gran cantidad de ciclos de coincidencia redundantes. En cuanto a las imlementaciones específicas del código, es mejor que sigan el comportamiento sugerido. Un ejemplo notable de desorden es el almacenamiento en caché de IE7 de las referencias ': first-child' –

Cuestiones relacionadas