llamar - selector padre css
¿Qué selectores o reglas de CSS pueden afectar de manera significativa el diseño de la interfaz de usuario/el rendimiento de representación en el mundo real? (6)
Aunque no está directamente relacionado con el código, usar <link>
sobre @import
para incluir sus hojas de estilo proporciona un rendimiento mucho más rápido.
''No use @import'' a través de stevesouders.com
El artículo contiene numerosos ejemplos de prueba de velocidad entre cada tipo, e incluye un tipo con otro (por ejemplo, un archivo CSS llamado a través de <link>
también contiene @import
a otro archivo css).
¿Vale la pena preocuparse por el rendimiento de representación de CSS? ¿O deberíamos simplemente no preocuparnos por la eficiencia en absoluto con CSS y centrarnos en escribir CSS elegante o mantenible en su lugar?
Esta pregunta pretende ser un recurso útil para los desarrolladores de aplicaciones para el usuario en el que las partes de CSS realmente pueden tener un impacto significativo en el rendimiento del dispositivo, y qué dispositivos / navegadores o motores pueden verse afectados. Esta no es una pregunta acerca de cómo escribir CSS elegante o mantenible, se trata solo de rendimiento (aunque es de esperar que lo que está escrito aquí pueda informar artículos más generales sobre mejores prácticas).
Evidencia existente
Google y Mozilla han escrito pautas para escribir CSS eficiente y el conjunto de reglas de CSSLint incluye:
Evite los selectores que se parecen a expresiones regulares. No use los operadores complejos de igualdad para evitar penalizaciones de rendimiento.
pero ninguno de ellos proporciona ninguna evidencia (que yo pueda encontrar) del impacto que estos tienen.
Un artículo de css-tricks.com sobre CSS eficiente argumenta (después de esbozar una carga de mejores prácticas de eficiencia) que no deberíamos not .. sacrifice semantics or maintainability for efficient CSS
estos días.
Una publicación de blog de matanzas de la perfección sugiere que border-radius
y box-shadow
representan órdenes de magnitud más lentas que las reglas de CSS más simples. Esto fue muy significativo en el motor de Opera, pero insignificante en Webkit. Además, un banco de pruebas de CSS de la revista Smashing encontró que el tiempo de renderización para las reglas de visualización de CSS3 era insignificante y significativamente más rápido que la representación del efecto equivalente con imágenes.
Sepa que su móvil probó varios navegadores móviles y descubrió que todos procesaban CSS3 con la misma insignificancia (en 12 ms), pero parece que lo hicieron en una PC, por lo que no podemos inferir nada sobre cómo los dispositivos portátiles funcionan con CSS3 en general.
Hay Google Mozilla en Internet sobre cómo escribir CSS eficiente. Sin embargo, aún no he encontrado ninguna evidencia exhaustiva de que el CSS mal considerado en realidad tenga un impacto significativo en el tiempo de renderizado o la apariencia de un sitio.
Fondo
Ofrecí una recompensa por esta pregunta para tratar de usar el poder de la comunidad de SO para crear un recurso útil bien investigado.
La mayoría de las respuestas aquí se centran en el rendimiento del selector como si fuera lo único que importa. Trataré de cubrir algunos trivia de sprites ( alerta de spoiler: no siempre son una buena idea ), css usó el rendimiento de valor y la representación de ciertas propiedades.
Antes de llegar a la respuesta, permítanme obtener un IMO fuera del camino: personalmente, estoy totalmente en desacuerdo con la necesidad declarada de "datos basados en evidencia" . Simplemente hace que una afirmación sobre el rendimiento parezca creíble, mientras que en realidad el campo de los motores de representación es lo suficientemente heterogéneo como para hacer que cualquier conclusión estadística sea inexacta e inaplicable.
Como los descubrimientos originales se vuelven obsoletos rápidamente, prefiero ver que los desarrolladores iniciales entienden los principios fundamentales y su valor relativo frente a los puntos de mantenimiento / legibilidad: después de todo, la optimización prematura es la raíz de todo mal ;)
Comencemos con el rendimiento del selector:
Los selectores específicos poco profundos, preferiblemente de un nivel, se procesan más rápido. En la respuesta original faltan las métricas de rendimiento explícitas pero el punto clave permanece: en tiempo de ejecución, un documento HTML se analiza en un árbol DOM que contiene N
elementos con una profundidad D
promedio y que tiene un total de reglas S
CSS aplicadas. Para reducir la complejidad computacional O(N*D*S)
, debe
Haga que las teclas de la derecha coincidan con la menor cantidad de elementos posible : los selectores se combinan de derecha a izquierda ^ para la elegibilidad de la regla individual, de modo que si la clave de la derecha no coincide con un elemento en particular, no es necesario seguir procesando el selector y es descartado
Se acepta comúnmente que
*
debe evitar el selector, pero este punto debe tomarse más. Un restablecimiento de CSS "normal", de hecho, coincide con la mayoría de los elementos: cuando esta SO se perfila, el restablecimiento es responsable de aproximadamente 1/3 de todo el tiempo de coincidencia del selector, por lo que puede preferir normalize.css ( aún así, eso solo suma a 3.5ms - el punto contra la optimización prematura se mantiene fuerte )Evite los selectores de descendientes ya que requieren que se iteren hasta
~D
elementos. Esto afecta principalmente las confirmaciones de falta de coincidencia, por ejemplo, una.container .content
positiva de.container .content
solo puede requerir un paso para los elementos en una relación padre-hijo, pero el árbol DOM deberá atravesar todo el camino hastahtml
antes de que una coincidencia negativa pueda ser confirmado.Minimice el número de elementos DOM a medida que sus estilos se aplican individualmente ( vale la pena señalar, esto se compensa con la lógica del navegador, como el almacenamiento en caché de referencia y los estilos de reciclaje de elementos idénticos, por ejemplo, cuando se diseñan hermanos idénticos )
Elimine las reglas no utilizadas ya que el navegador termina teniendo que evaluar su aplicabilidad para cada elemento procesado. Ya he dicho suficiente: la regla más rápida es la que no está allí :)
Esto dará como resultado mejoras cuantificables (pero, dependiendo de la página, no necesariamente perceptibles) desde el punto de vista del rendimiento del motor de renderizado, sin embargo, siempre hay factores adicionales tales como sobrecarga de tráfico y análisis DOM, etc.
A continuación, el rendimiento de las propiedades de CSS3:
CSS3 nos trajo (entre otras cosas) esquinas redondeadas, degradados de fondo y variaciones de sombra paralela, y con ellos, un camión cargado de problemas. Piénselo, por definición, una imagen renderizada previamente funciona mejor que un conjunto de reglas CSS3 que debe representarse primero. De la wiki de webkit :
Los degradados, las sombras y otras decoraciones en CSS deben usarse solo cuando sea necesario (por ejemplo, cuando la forma es dinámica en función del contenido); de lo contrario, las imágenes estáticas siempre son más rápidas.
Si eso no es lo suficientemente malo, los degradados, etc. pueden tener que ser recalculados en cada evento de repintado / reflujo (más detalles a continuación). Tenga esto en cuenta hasta que la mayoría de los usuarios puedan navegar por una página css3-heavy como esta sin un retraso notable.
A continuación, rendimiento spriting:
Evite los sprites altos y anchos , incluso si su huella de tráfico es relativamente pequeña. Comúnmente se olvida que un motor de renderizado no puede funcionar con gif / jpg / png y en el tiempo de ejecución todos los activos gráficos se manejan como mapas de bits sin comprimir. Al menos es fácil de calcular: el ancho de este sprite multiplicado por cuatro por bytes (RGBA) es 238*1073*4≅1MB
. Úselo en algunos elementos en diferentes pestañas abiertas simultáneamente, y agrega rápidamente un valor significativo.
Un caso bastante extremo ha sido recogido en mozilla webdev , pero esto no es del todo inesperado cuando se usan prácticas cuestionables como los sprites diagonales .
Una alternativa a considerar es imágenes individuales codificadas en base64 integradas directamente en CSS.
Luego, refluye y repinta:
Es un error pensar que un reflow solo se puede desencadenar con la manipulación JS DOM; de hecho, cualquier aplicación de estilo que afecte el diseño lo activaría afectando al elemento objetivo, sus elementos secundarios y posteriores, etc. La única forma de evitar iteraciones innecesarias de es intentar y evitar renderizar dependencias . Un ejemplo directo de esto sería renderizar tablas :
Las tablas a menudo requieren varias pasadas antes de que el diseño esté completamente establecido, ya que son uno de los pocos casos en que los elementos pueden afectar la visualización de otros elementos que aparecieron antes que ellos en el DOM. Imagine una celda al final de la tabla con un contenido muy amplio que hace que la columna se redimensione por completo. Esta es la razón por la cual las tablas no se representan progresivamente en todos los navegadores.
Haré ediciones si recuerdo algo importante que se ha perdido. Algunos enlaces para terminar con:
http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/
http://jacwright.com/476/runtime-performance-with-css3-vs-images/
https://developers.google.com/speed/docs/best-practices/payload
https://trac.webkit.org/wiki/QtWebKitGraphics
https://blog.mozilla.org/webdev/2009/06/22/use-sprites-wisely/
Lo primero que viene a la mente es: ¿qué tan inteligente es el motor de renderizado que está usando?
Eso, genérico como suena, importa mucho cuando se cuestiona la eficiencia del renderizado / selección de CSS. Por ejemplo, supongamos que la primera regla en su archivo CSS es:
.class1 {
/*make elements with "class1" look fancy*/
}
Entonces, cuando un motor muy básico ve eso (y ya que esta es la primera regla), va y observa cada elemento en su DOM, y verifica la existencia de la class1
en cada uno. Los mejores motores probablemente asignan nombres de clase a una lista de elementos DOM, y usan algo parecido a una tabla hash para una búsqueda eficiente.
.class1.class2 {
/*make elements with both "class1" and "class2" look extra fancy*/
}
Nuestro ejemplo "motor básico" iría y revisitaría cada elemento en DOM buscando ambas clases. Un motor más inteligente comparará n(''class1'')
n(''class2'')
donde n(str)
es el número de elementos en DOM con la clase str
, y toma el que sea mínimo; supongamos que es de class1
, luego pasa todos los elementos con class1
buscando elementos que también tengan class2
.
En cualquier caso, los motores modernos son inteligentes (mucho más inteligentes que el ejemplo discutido anteriormente), y los nuevos procesadores brillantes pueden hacer millones (decenas de millones) de operaciones por segundo. Es bastante improbable que tenga millones de elementos en su DOM, por lo que el peor de los casos para cualquier selección ( O(n)
) no será tan malo de todos modos.
Actualizar:
Para obtener alguna prueba ilustrativa práctica real, he decidido hacer algunas pruebas. En primer lugar, para tener una idea de cuántos elementos de DOM podemos ver en promedio en las aplicaciones del mundo real, echemos un vistazo a cuántos elementos tienen las páginas web de algunos sitios populares: Facebook: ~ 1900 elementos (probados en mi página principal personal).
Google : ~ 340 elementos (probados en la página principal, sin resultados de búsqueda).
Google: ~ 950 elementos (probados en una página de resultados de búsqueda).
Yahoo! : ~ 1400 elementos (probados en la página principal).
: ~ 680 elementos (probados en una página de preguntas).
AOL: ~ 1060 elementos (probados en la página principal).
Wikipedia: ~ 6000 elementos, 2420 de los cuales no son spans
o anchors
(Probado en el artículo de Wikipedia sobre Glee ).
Twitter: ~ 270 elementos (probados en la página principal).
Si sumamos esto, obtenemos un promedio de ~ 1500 elementos. Ahora es el momento de hacer algunas pruebas. Para cada prueba, divs
1500 divs
(anidados dentro de algunos otros divs
para algunas pruebas), cada uno con atributos apropiados según la prueba.
Los exámenes
Los estilos y elementos son todos generados usando PHP. Subí los PHP que utilicé y creé un índice para que otros puedan realizar pruebas localmente: pequeño enlace .
Resultados:
Cada prueba se realiza 5 veces en tres navegadores (se informa el tiempo promedio): Firefox 15.0 (A), Chrome 19.0.1084.1 (B), Internet Explorer 8 (C):
A B C
1500 class selectors (.classname) 35ms 100ms 35ms
1500 class selectors, more specific (div.classname) 36ms 110ms 37ms
1500 class selectors, even more specific (div div.classname) 40ms 115ms 40ms
1500 id selectors (#id) 35ms 99ms 35ms
1500 id selectors, more specific (div#id) 35ms 105ms 38ms
1500 id selectors, even more specific (div div#id) 40ms 110ms 39ms
1500 class selectors, with attribute (.class[title="ttl"]) 45ms 400ms 2000ms
1500 class selectors, more complex attribute (.class[title~="ttl"]) 45ms 1050ms 2200ms
Experimentos similares:
Al parecer, otras personas han llevado a cabo experimentos similares; este tiene algunas estadísticas útiles también: pequeño enlace .
La línea de fondo:
A menos que le importe ahorrar unos pocos milisegundos al renderizar (1ms = 0.001s), no se preocupe por pensarlo demasiado. Por otro lado, es una buena práctica evitar el uso de selectores complejos para seleccionar subconjuntos grandes de elementos, ya que eso puede marcar una diferencia notable (como podemos ver en los resultados de las pruebas anteriores). Todos los selectores comunes de CSS son bastante rápidos en los navegadores modernos. Supongamos que está creando una página de chat, y desea diseñar todos los mensajes. Sabes que cada mensaje está en un div
que tiene un title
y está anidado dentro de un div
con una clase .chatpage
. Es correcto usar .chatpage div[title]
para seleccionar los mensajes, pero también es una mala práctica para la eficiencia. Es más simple, más fácil de mantener y más eficiente para dar una clase a todos los mensajes y seleccionarlos usando esa clase.
La conclusión elegante de una línea:
Cualquier cosa dentro de los límites de "sí, este CSS tiene sentido" está bien .
Por una recompensa tan grande estoy dispuesto a arriesgar la respuesta nula: no hay selectores CSS oficiales que causen desaceleraciones apreciables en el procesamiento, y (en este día de computadoras rápidas e iteración rápida del navegador) cualquiera que se encuentre sea rápidamente resuelto por los fabricantes de navegadores. Incluso en navegadores móviles no hay problema, a menos que el desarrollador incauto esté dispuesto a usar selectores jQuery no estándar. Estos son marcados como riesgosos por los desarrolladores de jQuery, y de hecho pueden ser problemáticos.
En este caso, la falta de pruebas es evidencia de la falta de problemas. Por lo tanto, use el marcado semántico (especialmente OOCSS) e informe cualquier desaceleración que encuentre al usar selectores CSS estándar en buscadores oscuros.
Gente del futuro: los problemas de rendimiento de CSS en 2012 ya eran cosa del pasado.
Si bien es cierto que
las computadoras fueron mucho más lentas hace 10 años.
También tiene una variedad mucho más amplia de dispositivos que son capaces de acceder a su sitio web en estos días. Y aunque los equipos de sobremesa / portátiles han avanzado a pasos agigantados, los dispositivos en el mercado de teléfonos inteligentes de gama media y baja, en muchos casos no son mucho más potentes que los que teníamos en los equipos de sobremesa hace diez años.
Pero una vez dicho esto, la velocidad de selección de CSS probablemente esté en la parte inferior de la lista de cosas de las que debe preocuparse en términos de proporcionar una buena experiencia al rango de dispositivo más amplio posible.
Ampliando esto no pude encontrar información específica relacionada con navegadores más modernos o dispositivos móviles que luchan con selectores de CSS ineficaces, pero pude encontrar lo siguiente:
http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/
Bastante anticuado (IE8, Chrome 2) ahora, pero tiene un intento decente de establecer la eficiencia de varios selectores en algunos navegadores y también trata de cuantificar cómo el número de reglas de CSS afecta el tiempo de renderización de la página.
http://www.thebrightlines.com/2010/07/28/css-performance-who-cares/
Nuevamente bastante anticuado (IE8, Chrome 6) pero llega a extremos en selectores de CSS ineficientes
* * * * * * * * * { background: #ff1; }
* * * * * * * * * { background: #ff1; }
para establecer la degradación del rendimiento.
no es una manera irrelevante de hacerlo más rápido, debe ser lo último que mires cuando mires el rendimiento. Haga su CSS de la forma que lo permita, compílelo. y luego ponerlo en la cabeza. Esto puede ser difícil, pero hay muchas otras cosas que debes buscar cuando buscas en el rendimiento del navegador. Si trabajas en una oficina digital, no te pagarán por hacer 1ms extra en tiempo de carga.
Como comenté use la velocidad de la página para Chrome, es una herramienta de Google que analiza el sitio web en 27 parámetros. Css es 1 de ellos.
Mi publicación solo se refiere exactamente, no preferiría que alrededor del 99% de los usuarios de la web pudieran abrir el sitio web y verlo bien, incluso las personas con IE7 y tal. Que cierre un 10% usando css3, (Si resulta que puede obtener un extra de 1-10ms en rendimiento).
La mayoría de las personas tiene al menos 1mbit / 512kbit o más, y si carga un sitio pesado, se necesitan aproximadamente 3 segundos para cargar, pero puede ahorrar 10 ms en CSS?
Y cuando se trata de dispositivos móviles, debes crear sitios solo para móviles, así que cuando tienes un dispositivo con un tamaño de pantalla inferior a "Ancho" px, tienes un sitio separado
Por favor, comenta a continuación esta es mi perspectiva y mi experiencia personal con el desarrollo web