Precio caro de los estilos. Informe Yandex

Cargar CSS en una página es una operación de bloqueo. Si la carga asincrónica de JavaScript puede no ser visible para el usuario, la apariencia lenta de los estilos puede conducir a un invitado impaciente desde el sitio. ¿Cómo cargar CSS de la manera más eficiente y transparente posible para los usuarios? Nikita Dubko está tratando de descubrirDarkMeFoDy del grupo de interfaz de búsqueda Yandex en Minsk.


- Hola a todos. Te contaré sobre los estilos. Todos hablan de TypeScript y TypeScript hoy. Y hablaré sobre el guión de estilo Cascade.

Poco sobre mí. Soy un desarrollador bielorruso. Después de la película Dudya, lo diré en todas partes. Es posible que haya escuchado mi voz en el podcast de Web Standards, y si ve errores tipográficos en las noticias de Web Standards, probablemente sea yo también.

Pequeño descargo de responsabilidad. Habrá varias locuras en el informe: trate todo lo que digo con gran crítica. Piense por qué puede usar tales técnicas y por qué no las necesita. Algunas cosas serán realmente locas. Vamos.

¿Para qué?


Para empezar, ¿por qué hablar de optimización CSS?

Si comienzas a buscar en los motores de búsqueda descargas rápidas de JS, hay muchos resultados. Si busca una carga rápida de CSS, la parte superior ni siquiera muestra el CSS que necesita.



Si nos fijamos en Google, hay 111 millones de resultados sobre JS, y sobre CSS solo 26 millones.

Entonces, ¿tal vez esto no importa? ¿Por qué hablar de eso? Si busca informes de rendimiento de JS, encontrará muchos de ellos. Hay sobre React, sobre todo tipo de otros frameworks, sobre Vanilla, etc. Pero sobre CSS, encontré solo un informe. Harry Roberts en 2018 leyó un excelente informe sobre el rendimiento de CSS. Pensé que encontré un segundo informepor Roma Dvornova, "Parsim CSS: consejos y trucos de rendimiento". Pero resultó ser un informe JS que analiza CSS. No es exactamente lo que necesitamos.

Resulta que no piensan mucho en CSS. Es una pena.

Pero cuando voy a la web, generalmente veo HTML. Y también veo CSS que estiliza la página. Pero no veo a JS. JS es una cosa que mueve CSS y HTML en una página para que todo se vea hermoso. Este es un guión. Y si JS no se carga, no es tan malo como si CSS no se carga.

Los errores en JS caen silenciosamente en la consola. Y es poco probable que el usuario promedio ingrese a DevTools para mirar: "Oh, lo tienes ahí, un error en la consola". Pero si CSS no se carga, es posible que no vea todo lo que necesita.

Por cierto, hay estudios sobre el hecho de que lo principal es causar una primera impresión.El 38% de los usuarios pueden ir al sitio, y si ven que es directamente desagradable, se irán de inmediato. Y el 88% lo tolerará, lo usará una vez, y luego nunca volverán y es poco probable que aconsejen a su sitio.

Ahora que todos estamos sentados en casa, el tráfico de Internet ha crecido especialmente. Y debemos pensar en cómo entregar eficientemente los recursos a los usuarios.

Tratemos de contar desde el punto de vista de Yandex. Si podemos optimizar cada entrega de Yandex por 100 ms y dar, digamos, 200 millones de páginas por día (no sé el número exacto), entonces este día ahorraremos 0.1 s * 200 millones = 232 días-persona. Simplemente optimizando la salida para 100 milisegundos. Y CSS hace eso también.

Juguemos un poco a los detectives y descubramos cómo aprovechar al máximo los estilos de carga.

¡Medida!


El primer consejo es medir siempre todo. No tiene sentido hacer optimizaciones teóricamente. Puede suponer que la optimización funciona en su caso, pero las mediciones reales mostrarán que nada de eso. Esta es la regla más importante de cualquier optimización. Andrei Prokopyuk del equipo SERP Velocity en HolyJS habló muy bien sobre cómo hacemos esto , no me repetiré.

¿Qué herramientas de medición hay?

- Si desea medir en dispositivos más o menos reales, lentos, no tan geniales como los suyos, use WebPageTest . Usualmente tomo medidas allí.

- Tienes Lighthouse si usas navegadores basados ​​en Chromium. Él, como las mediciones locales, muestra cosas bastante buenas.

- Si está seguro de que puede hacer todo usted mismo, vaya a DevTools, a la pestaña Rendimiento. Tiene muchos detalles, puede comenzar sus propias métricas y analizarlas.



Naturalmente, en Performance es necesario establecer condiciones reales. Estás sentado en tu portátil genial con Internet genial en la oficina, todo es increíble aquí mismo, pero vienen a ti y te dicen: "Soy lento". Y usted dice: "Todo funciona para mí". No hagas así.

Siempre trate de verificar cómo el usuario en las condiciones del metro o en otro lugar utilizará su sitio. Para hacer esto, necesita configurar un Internet muy lento. También es aconsejable reducir la velocidad de la CPU, ya que alguien puede acudir a usted desde algún Nokia 3110. También debe mostrar el sitio.

Lo más importante: medir en usuarios reales. Existe una métrica de este tipo, más precisamente, un conjunto completo de métricas: RUM, Real User Monitoring. Esto es cuando mide no lo que sucede sintéticamente en su código, sino las métricas de usuarios reales en producción. Por ejemplo, desde cargar una página hasta una acción. Una acción es, por ejemplo, algo que funciona en el navegador o incluso un clic en algún elemento importante.

Recuerda que no estás desarrollando para robots. Sotka en Lighthouse: es genial, es realmente bueno. Por lo tanto, cumple al menos los requisitos que establece el Faro. Pero hay usuarios reales, y si el usuario no puede ver la página cuando está en Lighthouse, está haciendo algo mal.



Hay métricas en las que es importante enfocarse. Esta es la primera pintura con contenido, cuando aparece el primer contenido en su página con el que puede hacer algo, lea. Esta métrica se envía en los navegadores Chromium, puede obtenerla.



Recientemente, aún puede ver la pintura más grande y contenta. A menudo sucede que tiene una página de medios, y es importante, por ejemplo, mirar una foto en ella. Entonces necesitas esta métrica particular.

Carga de CSS


Pasemos finalmente a CSS, cómo se carga CSS. Las recepciones se conocen desde hace mucho tiempo. Hay una ruta de representación crítica, una ruta de representación crítica. Se trata de lo que hace el navegador desde el momento en que envía la solicitud del recurso hasta el momento en que los píxeles se muestran en la pantalla del usuario. Sobre esto, también, hay un montón de artículos e informes. Pero echemos un vistazo rápido a cómo lo hace este navegador.

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS —  </title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
</head>

Comienza a descargar HTML, ve las etiquetas. Poco a poco los analiza, comprende qué hacer con ellos. Cargas Encontré enlace. Debe ser usado. ¿Pero cómo? Primero necesitas descargarlo. La descarga es lenta. Cuando se carga, comienza a analizar más la página.

 <!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS —  </title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
</head>
<body>
    <h1>-!</h1>
</body>
</html>

Si se topa con otro enlace, se bloquea nuevamente y no permite la ejecución. Bloques JS, bloques de análisis. Y hasta que arranque, no hace nada. Pero luego comienza a trabajar más.

<enlace>


Profundicemos: ¿qué sucede cuando accede al enlace?



Grabar a dónde vamos es estándar. Hay un estilo CSS que se encuentra en alguna parte. Ahora está de moda poner todas las estadísticas en el CDN.

¿Dónde ir?


Primero, el navegador necesita entender a dónde ir.



Él ve la URL y necesita entender esta URL: ¿de qué se trata? Estamos acostumbrados al hecho de que la URL es un identificador de sitio.



Pero físicamente necesitamos obtener la dirección IP de esta URL e ir a la máquina física real en la dirección IP.



Para su CDN, recibirá un registro en DNS y en realidad irá directamente a la dirección IP. ¿Cómo se puede acelerar en este caso?



Una idea descabellada es reducir la distancia del usuario al servidor DNS. Tomar y trasplantar al usuario. Por ejemplo, para mostrar el mensaje: "Siéntate más cerca" o "Acércate".

Puede especificar inmediatamente la dirección IP en el enlace. ¿Por qué necesitamos buscar DNS, resolver dominios, si puede dar el resultado inmediatamente por dirección IP? Esta es una forma loca, pero en el caso de los servidores DNS globales DDoS, incluso puede salvarte.

Y podemos deshacernos de obtener una dirección IP.



Volviendo a su index.html u otro archivo, ya sabe la dirección de dominio donde va. Este es solo el caso cuando, en lugar de almacenar estadísticas en un dominio o subdominio separado, puede colocar las estadísticas más cerca de su dominio, es decir, este dominio en sí. Entonces DNS no necesita ser resuelto, ya lo está.



Descubrimos a dónde ir. Pero podemos hacer tales cosas por adelantado para el navegador. Si, por ejemplo, su hoja de estilo se carga mucho más tarde a través del árbol DOM, puede decirle al navegador usando <link rel = "dns-prefetch"> que "aún no voy allí, pero calentará los recursos, definitivamente los necesitaré más tarde ".

Con esta entrada, le dice al navegador que baje y obtenga este DNS. Cuando aparece un enlace en el código, el navegador ya sabrá la dirección IP de este dominio. Puedes hacer esas cosas preliminares. Lo mismo, por ejemplo, antes de ingresar a la siguiente página, donde definitivamente irá.

Ok, el navegador sabe a dónde ir. Necesita entender cómo ir.

Como ir


Estamos viendo el protocolo. Ahora, por supuesto, https es un requisito directo. La inclusión de motores de búsqueda marcará sus sitios que no están en https con formularios como no totalmente seguros.

Encontré una increíble serie de cómics sobre cómo funciona el tablero https. Pero somos personas de TI, nos encantan los diagramas complejos y geniales, y los cómics divertidos son demasiado fáciles.



Aquí he formulado en mis propias palabras cómo funciona https. Primero obtienes un certificado SSL de tu servidor. Luego debe verificar el certificado en una autoridad de certificación. Estos son servidores especiales que saben qué es válido y qué no, y pueden solicitar navegadores: "sí, todo está bien aquí, use este certificado".

Lo siguiente es la generación de claves para la comunicación entre el servidor y el cliente, cifrado, descifrado utilizando diferentes claves. El proceso es interesante si lo miras en términos de criptografía. Pero queremos acelerar. ¿Cómo?



Nuevamente podemos transferir al usuario más cerca de los servidores. Ya tenemos un DNS, ahora podemos acercarlo a la autoridad de certificación. Y poner entre estos servidores será perfecto.

Puede optar por no recibir https, ¿por qué lo necesitamos? Dedicamos tiempo a obtener un certificado, cifrarlo, descifrarlo. Realmente no. Este es el consejo más dañino en el informe, no lo hagas. https es protección de datos del usuario, y http / 2 no funcionará sin https, y http / 2 es otra forma de acelerar.



También hay tecnología de grapado OCSP. Puede verificar un certificado sin una autoridad de certificación. Esto probablemente esté más cerca de DevOps. Debe configurar su servidor de cierta manera para que pueda almacenar en caché la respuesta de la Autoridad de Certificación y emitir al usuario: "Créame, mi certificado es realmente real". Por lo tanto, podemos guardar al menos el paso en el que vamos a la Autoridad de Certificación.

Pero hay un matiz: en Chrome esto no funciona, y durante mucho tiempo. Pero para el usuario de otros navegadores, puede acelerar este proceso.

Ya he dicho dos veces que es necesario trasplantar al usuario, y la idea se está disparando en el aire: acercar el servidor al usuario. No he descubierto nada nuevo para ti. Esta es una CDN, una red de distribución de contenido distribuido. La idea es que puede usar sidienki ya preparado, crear de forma independiente su propia infraestructura y poner un montón de servidores en todo el mundo, en la medida en que el dinero y las oportunidades lo permitan. Pero debe organizar el servidor para que un usuario de Australia vaya a los servidores australianos. Aquí la velocidad de la luz juega contigo, cuanto más pequeña es la distancia, más rápido pasan los electrones.

Vamos a cavar más profundo. ¿Qué más está pasando en la solicitud? De hecho, https es solo un contenedor sobre http. No solo un envoltorio genial. Y si es aún más profundo, entonces http es una solicitud de la familia TCP / IP.



¿Cómo se envían los paquetes y bytes en la red para que todos los navegadores, clientes y servidores se comuniquen entre sí? Lo primero que hace un cliente / servidor a través de una conexión TCP / IP es un apretón de manos.

Pero en 2020, la OMS recomienda evitar los apretones de manos. Existe una tecnología TCP Fast Open tan genial. Puede, en el momento del apretón de manos, evitar toda la cadena "Hola, soy un cliente" - "Hola, soy un servidor" - "Te creo" - "Y te creo. Vamos". Ya puede enviar datos útiles en este momento. Y si el apretón de manos fue exitoso, entonces una parte de los datos útiles ha pasado. Esto es TCP Fast Open.

¿Qué recoger?


Veamos qué debe recoger el cliente del servidor. Lo principal no es que el cliente toma algo del servidor, sino que el servidor entrega los datos al cliente. Entonces podrías pensar: User-Agent. Puedo obtener el User-Agent del cliente, averiguar en qué navegador ha iniciado sesión el usuario. Averigüe aproximadamente si no me engaña, este navegador.

.example {
    display: -ms-grid;
    display: grid;
    -webkit-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
    background: -o-linear-gradient(top, white, black);
    background: linear-gradient(to bottom, white, black);
}

Digamos que inició sesión desde Firefox. Yo, como de costumbre, tengo un ensamblaje en el que el corrector automático está conectado de forma cursi, ha generado un montón de código para mí. Sí, este es un enfoque genial de que todo funcionará en todas partes. Pero ya sé que el usuario ha iniciado sesión desde Firefox.

¿Por qué no apagar todo el exceso? De acuerdo, hay muchas menos líneas, enviamos menos bytes, esto es genial.

Tenemos una versión lite de SERP, Granny. Vitaly Kharisov habló de ellavithar, informe de clase sobre los días de estándares web. Utiliza exactamente este enfoque. Podemos generar varios paquetes y dárselos a diferentes clientes de diferentes maneras. Pesan mucho menos, porque Firefox tiene el suyo, WebKit tiene el suyo y funciona, está verificado.



Más lejos. Lo más probable es que procesemos las solicitudes de los usuarios, sabemos que la persona está autorizada y usamos cierta información personal para él. Es lógico que obtengamos algo de la base de datos. ¡Pero no todos! Hay cosas estáticas que no difieren para ninguno de los usuarios, son exactamente lo mismo.

James Akvuh leyó un excelente informe al respecto"Representación del lado del servidor. Hazlo tu mismo". ¿Cual es el punto? Ya sabe que tiene HTML y algún tipo de CSS que es igual para todos los usuarios. Antes de buscar cualquier dato, puede generar la salida de estos datos estáticos, enviar de inmediato el más útil en una secuencia desde el servidor. Y después de eso, busque los datos, recíbalos rápidamente, conviértalos en plantillas y déselos al cliente. Y el usuario ya verá algo útil.



Hemos implementado esto hace mucho tiempo. Tenemos en SERP, en la página de búsqueda principal, dos fases: búsqueda previa y búsqueda posterior. La búsqueda previa es cuando enviamos todas las piezas que no necesitan conocimiento sobre qué usuario ha iniciado sesión. Ya podemos darle, por ejemplo, un sombrero.

Es decir, tenemos una barra de búsqueda que el usuario puede comenzar a usar antes de que todo lo demás se cargue. Esto es útil en una conexión lenta. Lo hacemos, funciona.

Y también hablé sobre http / 2. Esto es totalmente compatible con los navegadores modernos, por lo que si aún no lo ha configurado en su servidor, al menos descubra cómo configurarlo.

Server Push es una tecnología genial que dice: “Navegador, todavía no te he dado el conocimiento de que necesitas algún tipo de CSS. Pero sé exactamente lo que se necesita. Así que sostenlo, precargalo ”.





No es dificil. Debe configurar un par de encabezados en el servidor y todo comenzará a funcionar. Si el navegador no conoce este título, nada se romperá, este es el más hermoso. Vamos a cavar aún más. TCP Ya hablamos sobre esto: un apretón de manos, se envían bytes.



Lávese las manos después de un apretón de manos. Pero en términos de TCP, comenzamos a reenviar bytes, y los algoritmos están lo suficientemente optimizados para que el servidor del cliente no permanezca inactivo.

Por lo tanto, se envía primero un determinado segmento de datos. Por defecto, (esto puede cambiar en la configuración) es 1460 bytes. El servidor no envía información sobre un segmento. Él envía ventanas.

La primera ventana es 14600 bytes, diez segmentos. Luego, si la conexión es buena, comienza a agrandar las ventanas. Si la conexión es deficiente, puede reducir la ventana. ¿Qué es importante entender? Existe la primera ventana de diez segmentos, en la que debe ajustar todo el sitio, si lo desea. Y luego habrá una velocidad máxima de aparición del contenido. Vitaliy Kharisov también leyó un informe sobre esto . Y sí, es posible ajustar un sitio con todo lo que necesita en una ventana si desactiva, por ejemplo, JS.

Un matiz importante. Cuando llena un segmento completo, es un segmento. Pero si envía solo un byte adicional, el servidor aún enviará un segmento adicional completo.



Puede hacer una buena optimización, reducir la producción en un kilobyte completo, pero no verá nada en sus mediciones, tal vez debido a esto. Intente hacer la optimización normalmente en varios segmentos.

Extraño: soy un tipográfico, y le digo cosas tan complejas al servidor. Acerquémonos aún más al CSS real.

Enviar menos


Entonces, enviamos menos al usuario, menos segmentos, llega más rápido, el usuario está contento.



Minificación Ella estaba preparada para sus proyectos. Hay un montón de herramientas geniales, complementos de paquete web, configuraciones de trago; en general, lo descubrirá usted mismo. Puede personalizarlo a mano, pero parece solo cuando está seguro de que puede comprimir su enfriador CSS que cualquier CSSO.

Recuerde habilitar la compresión. Si al menos gzip no está activado en 2020, definitivamente está haciendo algo mal, porque esta es una antigua técnica de compresión. En general, en 2020, es hora de usar brotli. Esta es una buena manera de reducir ligeramente la salida en los navegadores Chromium. O, si no desea admitir brotli, al menos puede probar zopfli.

Este es un algoritmo de compresión bastante lento para gzip, que simplemente proporciona los mejores resultados de compresión y se descomprime tan rápido como gzip normal. Por lo tanto, zopfli debe configurarse sabiamente y usarse solo cuando no necesite generar datos sobre la marcha. Puede configurar los archivadores gzip para que se recopilen durante el ensamblaje utilizando el algoritmo zopfli y se envíen estáticamente, de hecho, no se ejecutan al vuelo. Esto te puede ayudar. Pero también mida los resultados.



Todos estos algoritmos utilizan algún tipo de diccionario: un diccionario se construye sobre la base de fragmentos de código repetidos. Pero a veces dicen: es necesario alinearse, si lo hacemos, nos deshacemos de la solicitud. Vincular todo el CSS en HTML será muy rápido. El truco es que gzip funciona un poco más eficientemente cuando desglosa estilos y HTML, porque los diccionarios son diferentes, más eficientes.

En mi caso, simplemente tomé la página de arranque, vinculé allí y comparé las dos versiones. Gzip sobre recursos individuales es 150 bytes menos. Sí, la ganancia es muy pequeña. Aquí también debes medir todo. Pero en su caso, esto puede, por ejemplo, reducir el número de segmentos en uno.

¿Cómo optimizar el código? No estoy hablando de minificación. Quite lo que no está usando en el proyecto. Lo más probable es que tenga un código que nunca se ejecutará en el cliente. ¿Para qué?



Para que pueda automatizar esto, hay pestañas especiales integradas en el navegador, por ejemplo, en Chrome DevTools, esto es Cobertura, que le dice: "No utilicé este CSS o este JS, puede cortarlo".

Pero es posible que tengas un elemento emergente, foco, activo, algo instalado usando JS. Debe simular todas las acciones posibles en el sitio, solo entonces estará seguro de que este CSS se puede cortar. Chris Coyer tiene un buen artículo de revisión sobre herramientas automáticas que intentan hacer todo con el mouse y el enfoque. Pero llegó a la conclusión de que era imposible automatizar esto. Aún no funciona.

Hay un buen informe de Anton Kholkin de Booking.com, donde también intentaron eliminar un montón de código heredado. Pero tenían una peculiaridad: un código heredado que provenía de proyectos externos. Era necesario quitarlo. Vea qué soluciones interesantes encontraron.

Usted mismo puede intentar jugar con el mismo Titiritero, que es como Chrome. Puede hacer pruebas que pasan automáticamente por todo, tratar de hacer flotar, concentrarse. Y use esta misma cobertura.

Mi colega Vitya Khomyakovvictor-homyakovhice mi propio script , como encontrar duplicados y estilos en una página. Solo toma, copia y pega. Él te escribirá en la consola: "este selector, al parecer, no lo necesitas". Hasta el punto que solo ingrese en DevTools. Es impresionante.



Una característica que realmente me gusta de las herramientas de los desarrolladores de Firefox: una oportunidad para ver estilos que parecen ser utilizados, pero de hecho el navegador no los aplica.

Por ejemplo, puede establecer display: inline, y parece que esta pantalla: inline no tiene sentido establecer tamaños. O alineación vertical, solo funciona en línea o celda de tabla. Hasta ahora, solo he visto en Firefox que puede resaltar: "no necesita esta línea".

Aquí también debes tener cuidado: quizás uses este estilo para luego pegar la clase. Pero en mi opinión, una característica genial.

Hágase la pregunta ahora mismo: ¿necesita todo el Bootstrap en el proyecto? Coloque cualquier marco CSS que use en lugar de Bootstrap. Lo más probable es que use Bootstrap para cuadrículas y elementos más o menos comunes, y la mitad de Bootstrap que no necesita.

Intente usar el ensamblaje correctamente. Casi todos los marcos CSS modernos le permiten usar el código fuente para el ensamblaje y seleccionar solo lo que necesita. Esto puede reducir drásticamente el tamaño del paquete CSS.

No regalar sin usar. En lugar de buscar mi legado, puede usar la comprensión de nivel de compilación de que esta página no usará este CSS.

Por ejemplo, una pila BEM completa le permite realizar el ensamblaje para que usted, ya dando la página, pueda construir un árbol de todos los componentes de los bloques BEM que estarán en la página. BEM le permite determinar que si este bloque no está en la página, no hay necesidad de cargar este CSS. Enviar solo lo necesario.

Incluso los chicos de Google dicen : use BEM, realmente puede ayudarlo para la optimización.

No creo que lo diga en voz alta, pero en este caso CSS-in-JS parece ser un buen enfoque. Cuando escribe componentes independientes independientes y configura cuidadosamente el ensamblaje o determina en tiempo de ejecución qué bloques se usan y cuáles no, puede deshacerse del problema de encontrar un código heredado simplemente no enviando este código al cliente. Suena fácil, pero se necesita disciplina. Piénselo de antemano al comienzo del proyecto.



¿Qué otra opción hay? Un poco loco. En este código, parece que el estilo no es necesario, porque usamos un div; el valor predeterminado ya se muestra: block. ¿Y eliminemos todos los valores predeterminados? Si en su proyecto sabe con certeza que el marcado HTML nunca volverá a cambiar, revise los valores predeterminados que el navegador ya proporciona y elimínelos.

Menos estilos, ¡genial! Pero esta es otra vez una idea loca. CSS no tiene que saber sobre HTML, porque es un estilo. Es bastante independiente, debe conectarlo a otro proyecto, debería funcionar allí. Y sí, es difícil de mantener. Cambia la etiqueta: todo se rompe. Idea loca como se prometió.

Utiliza variables. CSS tiene variables muy antiguas como currentColor.



A menudo hay un patrón: desea, por ejemplo, hacer un botón cuyo texto y borde tengan el mismo color. Y al pasar el ratón los cambiamos a ambos. ¿Para qué?



Hay una variable currentColor que toma un valor del color, y lo coloca, por ejemplo, en el borde, representa esta propiedad y cambia solo una línea al pasar el mouse, al enfocar, al activar, lo que desee. Esto parece ser conveniente, y el código se ha convertido en una línea menos. Puedes optimizar. Por cierto, en este ejemplo, no puede usar la tarea de color de borde en absoluto, porque de forma predeterminada ya toma un valor de la propiedad de color.

A veces es muy triste ver cómo se usa base64. En CSS, se recomendó activamente antes: use base64 para inyectar iconos pequeños. Si cabe en un segmento a través de TCP, es bueno para usted.



Pero Harry Roberts tambiénLlevó a cabo un estudio con clase sobre cómo base64 afecta la carga de la página. Sí, hay menos solicitudes, pero estos estilos se analizan a veces más lentamente.

De acuerdo, el análisis es una operación muy rápida, el usuario probablemente no lo notará. Pero tenemos una métrica importante: la primera representación, para que el usuario vea algo en la página. En teléfonos móviles, la primera representación, según un estudio de Harry Roberts, ocurre diez veces más tarde. ¿Piensa si necesita base64? Sí, hay menos solicitudes, pero ¿tuvo algún efecto?

Y por favor no use base64 para SVG. Porque SVG es excelente para usar el codificador de URL. Julia Bukhvalova tiene una herramienta genial: Entre, pegue su SVG y le dará CSS en un formulario listo para pegar. Puede notar que no hay base64, pero se escapan algunas cosas que en CSS pueden no percibirse correctamente. Es mucho más eficiente.

En promedio, base64 le da un plus del 30% al tamaño de lo que comprime. ¿Para qué?

Utiliza tecnología moderna. Es posible que debamos admitir Internet Explorer, los argumentos habituales cuando hablamos de cuadrículas.



Pero piénselo: si no tiene soporte para IE y todavía está escribiendo en flotante o tablas, puede usar cuadrículas para hacer un diseño de tres columnas con un espacio de 20 píxeles: esta es la distancia entre las columnas. Tres lineas. Bueno, cinco, considerando el anuncio en sí.

Prueba esto en un flotador. Y quiero decir que cambiamos tres líneas, incluido el nombre de las clases, si tocas HTML. No encontré una manera de hacer lo mismo genial en un flotador. Desecha tus decisiones. Pero usa la tecnología moderna. Le permiten indicar de forma más compacta el marcado.



Puedes probar Atomic CSS. ¿Qué es? Escribes estos nombres de clase un poco locos. Y después de un tiempo, comienza a comprender que es usted quien establece el color de fondo o simplemente el color. Estas son las "características" para CSS. Pero tiene un conjunto de CSS fijo que luego usa en HTML como una indicación de estilo. Y CSS de repente se está volviendo más pequeño. Para proyectos grandes, realmente se hará más pequeño, porque hay menos estilos únicos. Pero estás creciendo HTML.



Puede mirar en la dirección de Tailwind CSS, que ahora está ganando popularidad. No es Atomic CSS, se trata de clases de utilidad, similares a Bootstrap, solo que más utilitarias. Puedes usar un conjunto específico. Suficiente parece ser suficiente para ti. Un conjunto de clases que realizan sus funciones. También puedes intentarlo, pero no exageres demasiado.



Otra idea loca: ¿por qué necesitamos nombres completos de clase en el cliente? Sí, es conveniente para el desarrollo y la depuración, pero tomemos todos los nombres de clase y hagámoslos con una sola letra. Será menos

Aquí hay un artículo sobre cómo hacer esto. Puede configurar webpack u otro complemento al compilar. Pero no despegó de nosotros. Nosotros tratamos.

Resultó que gzip es tan genial que todo estaba bastante bien optimizado para nosotros, y BEM y gzip son increíblemente amigables. Porque las construcciones de texto se repiten para describir bloques y elementos en el código.

En general, esto casi no nos dio ganancias. Pero si, por ejemplo, no tiene BEM y un montón de clases diferentes, puede intentarlo.

Importante: medida. Mida todas esas piezas experimentales. Tal vez ahora funcione para usted, y luego cambió ligeramente la arquitectura del proyecto, comenzó a ensamblarse de manera diferente y todo se ralentizó.

¡Descargalo!


Hasta ahora, solo he hablado sobre cómo descargar un archivo. Lo descargamos. ¿Qué ha visto el usuario todo este tiempo?



Vio una pantalla tan asombrosa. Mientras estábamos descargando, la pantalla estaba en blanco. Lo descargamos y el navegador comienza seis pasos más. Tenga paciencia un poco, hablaré sobre ellos un poco más rápido que sobre la descarga.



Comencemos con el análisis. El análisis se produce cuando un navegador ha descargado una secuencia de bytes y comienza a dividirlo en entidades que comprende.



Por ejemplo, se encontró con la importación. Esto nuevamente debe ser descargado. ¿Leer de nuevo la primera parte del informe? importar es una operación de bloqueo. Pero los navegadores son inteligentes. Tienen un escáner de precarga. Dije que todo está bloqueado allí, esto no es cierto. Los navegadores saben que, por ejemplo, si hay tres etiquetas de enlace seguidas que siguen el estilo, cuando descargue el primero, puede comenzar a descargar el segundo y el tercero. No se puede analizar, porque toda la estructura del análisis se rompe. Pero descargue por adelantado, puede.



Entonces importar es algo malo. Si los estilos son consistentes en HTML, el navegador verá que iremos más allá para otro archivo.



Y si lo inserta directamente en la importación, primero debe descargar su style.css, luego ver la importación en él. Él comienza a analizar este CSS ... ¡Sí, bloqueamos todo de una manera nueva y buscamos el archivo! Para que pueda hacer una cascada fresca con desoptimización en el sitio.

Olvídate de la importación o configúralo para que no haya importación después de la compilación. Para el entorno de desarrollo, ok, pero no para el usuario.



A continuación, pasamos por las etapas de construcción de árboles, usando Cascade.



Todo esto también se describe durante mucho tiempo. Se construye el modelo de objetos CSS: un árbol especial de cómo el navegador asigna etiquetas, clases a estilos. Lo vincula todo al DOM y hace estas conexiones muy rápidamente. Cuando cambias algo, es suficiente para que él lo cambie dentro del árbol.



Cuanto más grande sea el selector, más difícil será para el navegador dibujar un árbol. Necesita analizar el selector, convertirlo en estructuras de árbol. Y si insertó! Importante allí, entonces debería tener esto en cuenta.



Parece que es hora de hablar de BEM nuevamente. Pero BEM no es necesario si sabe cómo usar las clases de utilidad, si una clase es responsable de una funcionalidad y no interfieren entre sí. Entonces construir un árbol es muy simple. Tiene una estructura bastante plana y luego el navegador debe vincularla correctamente al DOM.



Si hace esto, entonces dicen que tales selectores ralentizan el análisis CSS. Pero estas son leyendas hace mucho tiempo, la diferencia es tan pequeña para el navegador que en el proyecto promedio no lo notará si optimiza los selectores con asteriscos. ¿Pero le gustaría desarrollar y mantener ese código?



Solía ​​escuchar consejos: intente poner todo en un atajo. El fondo es un acceso directo para muchas otras propiedades. Ponemos todo en una propiedad, y se vuelve óptimo.

Por bytes, sí, se está volviendo más pequeño. Pero si desea optimizar la composición de CSS OM, entonces el navegador seguirá sacando todas estas propiedades del fondo. Los navegadores para cada elemento DOM crean una tabla de todas las propiedades que puede tener. Cuando observa los valores calculados de DevTools, no están allí porque el navegador los calculó de acuerdo con sus requisitos. Almacena esto en la memoria, porque es mucho más fácil reescribir una propiedad y todo funciona.

Este también es un consejo muy extraño, pero si desea que CSS OM sea más rápido, puede establecer de inmediato todas las propiedades de una en una. Aquello podría funcionar. Pero el tamaño del paquete aumentará considerablemente. Necesitas medir. Dudo que dé ganancias, ¡pero de repente!

Cuando se construye CSS OM, JS también está bloqueado en este punto. Si construir OM CSS toma dos segundos, JS falla. Aunque no puedo imaginar cómo lograste escribir tanto en CSS que el árbol se construye durante dos segundos.



Además el navegador hace diseño. Esta es la ubicación de todos los elementos DOM, el uso de posiciones. Él entiende dónde debe ubicarse el elemento y con qué dimensiones. Parece que en esta etapa el usuario ya debería ver algún tipo de imagen. Pero él ve todo en la ventana gráfica, puede mirar a través de una ventana limitada. Si algo no está bien desde abajo, simplemente no lo verá.



La idea se llama CSS crítico, y también es bastante antigua. Inserta algunas cosas importantes para la primera pantalla al comienzo de la descarga. Por ejemplo, en línea en su HTML, elimine cualquier solicitud adicional. El usuario ve primero esta pantalla y luego la descarga como desee. Lo más probable es que comience a desplazarse cuando tenga tiempo de cargarlo.



Esto se hace simplemente. Hay herramientas que automatizan todo esto, incluidos los complementos para webpack y React. Solo busca y configura correctamente.

- github.com/addyosmani/critical
- github.com/pocketjoso/penthouse
- github.com/anthonygore/html-critical-webpack-plugin
- github.com/GoogleChromeLabs/critters



Tenga un buen enfoquede Filament Group: cómo cargar de forma asincrónica sin bloquear CSS. Todo es bastante simple.

Cuando ponga <link rel = preload>, dígale al navegador: "Necesitaré este estilo, pero ahora no estamos bloqueando nada. Lo descargas ahora, lo guardas en caché y, cuando lo reviso, empiezo a construir CSS OM ". Y solo necesita poner onload y procesar eso "ok, desde que lo descargué, hágalo rel = stylesheet, enable parsing".

Un enfoque bastante simple, pero úsalo sabiamente también. Si tiene demasiada precarga, puede hacerlo peor.



También puedes jugar con expresiones multimedia. Péguelos y dígale al navegador: "este estilo no es necesario ahora, pero cuando esta expresión multimedia funcione, será necesario". El navegador también se descargará de manera proactiva, pero con menor prioridad y sin bloqueo.



Otro enfoque loco, pero no tan loco, cuando tienes http / 2 push. Puede incrustar CSS justo en frente del bloque. Sin CSS, su bloque no se verá muy bien. Entonces, ¿por qué no alinear el CSS que necesita para el siguiente bloque antes de este bloque? Esto es lógico, y la inserción http / 2 le permitirá optimizarlo.

Un enfoque simple. Si lo expande, use carga diferida. ¿Por qué un usuario debe descargar algo que no usará? Puede configurar los componentes React para que si nunca ha alcanzado el área de visibilidad de la página, ¿por qué debería descargar estilos por sí mismo?

Explore la API de Intersection Observer y podrá acelerar drásticamente su página.



El último paso es dibujar y aplicar a capas compuestas, pegarlas, etc.



El navegador crea capas compuestas en una gran cantidad de casos. En mi opinión, solo una cuarta parte del código fuente de Chromium encaja aquí . Puedes ver por ti mismo cuando crea capas compuestas en el código del navegador.

La memoria de video es limitada, especialmente en teléfonos móviles. Si lleva todo a nuevas capas para optimizar las animaciones usando will-change: transform u otra cosa, entonces puede estar peor.

Cree menos capas, exactamente la cantidad que necesita para la optimización actual.

Genial, todos analizamos.

¿Y si vuelvo?


¿Y si regreso a la página? Esta es solo la primera vez que fui.

Al volver a la página, parece que puedo descargar todo al instante. Ya descargué todos los recursos, ¿por qué no usarlos por segunda vez?



Si el servidor no proporciona el encabezado Cache-Control, el navegador intentará almacenar en caché su archivo para reutilizarlo. Puede configurar su servidor de manera predeterminada, por ejemplo: "guarde en caché este archivo durante todo un año". No cambiará. Pero si es así, debe lidiar con el problema de invalidación de caché global. Pero este es el tema de un informe separado.

¡Use trabajadores de servicio! 2020, es hora, aplicaciones web progresivas! Kirill Chugainov tuvo un buen informesobre cómo se pueden usar los Service Workers para diferentes ocasiones. En este caso, intercepta la solicitud CSS, guárdela y, si el navegador sigue este estilo por segunda vez, retírela del caché.

Pero el navegador no te promete nada. Siempre puede enfrentar el hecho de que el navegador se ha quedado sin memoria. Intentará almacenar en caché, pero no hay memoria. El almacenamiento en caché no es cien por ciento. Siempre maneja tales situaciones.

Puedes intentar usar el almacenamiento local. Pero él es muy lento. La descarga de un archivo a veces es más rápida que ir a la API de almacenamiento local.

Puede probar la base de datos del navegador incorporada. Pero mídelo. Quizás un viaje a JS te llevará más tiempo debido a un procesador débil.

También puede decirle al navegador de antemano que descargará algo.



<link rel>: aprenda cómo funciona este atributo. Hay una preconexión, una captación previa, una rendición previa. Quiero hablar de ello por separado. Él dice: “Estoy en esta página ahora, y luego iré a la siguiente. Descargue todo para esta página en la pestaña de fondo y dibuje ". Cosas interesantes. No funciona en ningún lado.



En cierto sentido, es compatible con IE y Edge. En Chrome, realmente no hace esto, no se procesa. Funciona como captación previa: descarga estos archivos y cachés. Desafortunadamente, una representación completa no funciona en ningún lado.

Pero puedes desarrollar esta idea. Por ejemplo, en la aplicación Yandex, naturalmente, sin usar CSS, se realiza una representación previa. Cuando está buscando algo, es probable que pueda obtener sus resultados al instante. Nosotros podemos predecir donde va a ir, y por adelantado por nuestros propios métodos de ir a buscar todos los recursos necesarios.

¿Que sigue? Había muchos enlaces. También te aconsejo que mires una increíble colección de optimización de todo, desde Vanya Akuloviamakulov. Vea cómo optimizar tanto HTML como JS y el ensamblaje.

Y no te olvides de ordenar. Ahora mi consejo realmente funciona, sugiriendo cómo hacerlo rápidamente, pero lo más probable es que, después de cinco años, incluso sean dañinos. Habrá algún tipo de tecnología que será incompatible con ellos. Haga un seguimiento de esto e intente mantener su código óptimo, incluso después de un tiempo. Gracias por la atención.

All Articles