Carga asíncrona de Css sin bloquear la composición de la página 1.4.15
Traslación al español del artículo original de Keith Clark "Loading CSS without blocking render"
Carga asíncrona de Css sin bloquear la composición de la página
Lo que te dispones a leer es una traslación no fidedigna al español del artículo de Keith Clark @keithclarkcouk [Loading CSS without blocking render
] publicado en su página el 30 de Marzo de 2015.
Haz el favor de consultar el original para estar al tanto de las revisiones y las actualizaciones que pueda hacer su autor.
Este artículo presenta una técnica para mostrar el contenido web a los visitantes lo más rápidamente posible mediante la descarga de forma asíncrona de las hojas de estilo para evitar que haya bloqueos en la composición de la página.
Las bases que inspiran estas técnicas no son nuevas. Filament group
, por ejemplo, ha publicado contenido de calidad sobre loading CSS y fonts. He escrito este artículo para documentar mis opiniones e sobre la carga de los recursos sin que causen bloqueos.
El truco para desencadenar una descarga de estilos asíncrona es utilizar un elemento link
y establecer un valor no válido para el atributo media
(yo uso media="none"
, pero cualquier otro valor sirve). Cuando una consulta de medios se evalúa como falsa, el navegador seguirá descargando la hoja de estilo, pero no va a esperar a que su contenido esté disponible antes de dibujar la página.
<link rel="stylesheet" href="css.css" media="none">
Una vez que la hoja de estilo ha terminado de descargarse el atributo media
se debe restablecer a un valor válido para que las reglas de estilo se apliquen al documento. Utilizo el evento onLoad
para cambiar el valor de media
a all
:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
Este método de carga del CSS mostará el contenido a los visitantes mucho más rápido que el método estándar. El CSS crítico se puede servir con el enfoque habitual de bloqueo (o puede ir en línea para un máximo rendimiento) y los estilos no críticos pueden ser descargados progresivamente y aplicados tras el proceso de carga y composición (render) de la página.
Esta técnica usa javascript, pero se puede prevenir su uso en los navegadores que no lo soporten o que el usuario lo tenga deshabilitado con el elemento noscript
:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
<noscript><link rel="stylesheet" href="css.css"></noscript>
Hay un efecto secundario de esta técnica. Una vez que una hoja de estilo no-bloqueante ha terminado de descargarse, el documento será redibujado para reflejar las nuevas reglas que contiene. La inyección de nuevos estilos en la página puede desencadenar reordenación de contenido [n.e.: ver repain y reflow], pero esto realmente sólo es un problema en la primera carga de la página con un caché sin imprimación. Al igual que con todas los temas relacionadas con el rendimiento, tendrás que evaluar los efectos del reflow frente a la potencial velocidad de carga.
Uso de Css no bloqueante en la carga de tipografías
Las fuentes tipográficas son un problema en la carga inicial de la página. Son un recurso bloqueante y pueden causar la desaparición del texto momentáneamente [n.e.: ver font loading, render, FOIT]. Usando esta técnica es posible descargar la tipografía en segundo plano sin causar demoras y bloqueos en la composición de la página.
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="font.css" media="none" onload="if(media!='all')media='all'">
font.css
conttendría una tipografía WOFF codificada en base64 (versión Merriweather font).
@font-face {
font-family: Merriweather;
font-style: normal;
font-weight: 400;
src: local('Merriweather'), url('data:application/x-font-woff;charset=utf-8;base64,...')
}
main.css
contendría todas las reglas restantes para estilizar la página, incluidas las declaraciones font-family: ...;
body {
font-family: Merriweather, "Lucida Grande", ...;
}
Mientras que la tipografía inicial se está descargando, se utiliza la primera fuente de reserva declarada (Lucida Grande, en este caso) que logra que el contenido de la página se muestre. Una vez que se aplica la hoja de estilo que contiene las reglas @font-face
, se utilizará Merriweather. Al usar familias tipográficas con características de diseño similares a la fuente preferida, el repintado inevitable del texto será tan sutil como sean las dos fuentes.
He confrontado en Google Analytics Debugger en Chrome los dos métodos de carga (el tradicional bloqueante y éste no-bloqueador) simulando una conexión 3G. Pruebas locales dan como resultado el siguiente gráfico de red.
Observa el valor de DOMContentLoaded
, con este método no bloqueador hay una ganancia de 450ms al comenzar la descarga de los recursos.
Implementando este método en un servidor de prueba y usando webpagetest con conexión 3G produce el siguiente cronograma:
A ambos métodos les lleva 2,8 segundos renderizar por completo la página, pero el método no-bloqueo hace que se comienze un segundo antes. La misma prueba con la hoja de estilo principal en línea muestra un aumento de 0,7s cuando se utiliza CSS sin bloqueo para servir la fuente:
Esta técnica funciona bien para las tipografías pero recomiendo echar un vistazo al nuevo módulo CSS Font Loading, que ofrece mucho mayor control sobre la carga de tipografías.
Conclusión
La cargando de fuentes es un ejemplo de aplicación de esta técnica de no bloqueo, pero también podría ser utilizada para otros fines, tales como la separación de los estilos Css básicos y fundamentales de los usados vía JavaScript para mejoras.
He empezado a experimentar con la idea de separar el CSS en módulos (layout básico) y presentación (todo lo demás), lo que impediría retrasos en la carga de los aspectos vitales de la página y aplicando efectos estéticos posteriormente.
Gracias a Mathias Bynens por facilitarme una versión simplificada del evento onLoad del link
Créditos y autoría del artículo original
Keith Clark es el autor de este artículo en su versión original en inglés:
Loading CSS without blocking render
publicado inicialmente en su página keithclark.co.uk
@keithclarkcouk en Twitter.
Haz el favor de consultar el original para estar al tanto de las revisiones y actualizaciones que pueda hacer su autor.
Con mis disculpas por los posibles (seguros) fallos por mala comprensión o traslación al español. Hecha con las mejores intención y con el único propósito de su difusión y conocimiento entre los usuarios de este blog.
Una pequeña prueba propia
Tras la lectura de este artículo hice unas pequeñas y muy rápidas pruebas de esta técnica en este blog recuerda que es un Blogger y como Blogger incluye los estilos mediante el elemento <style>
en el propio Html del blog yo introduje esta forma asíncrona en su carga en estos elementos, tanto en los generales que van en el head
como el que uso aparte y al final del body
para incluir las reglas @font-face de la tipografía.
Estas son las dos conclusiones principales:
- En Firefox sí noté cierta mejoría tanto en el inspector del navegador como en los datos facilitados por herramientas online que evalúan estos aspectos.
- En Chrome el uso de esta técnica en el elemento
<style>
supone que no se carguen los estilos incluidos en él.
Solamente un inglés puede tomarse el trabajo de separar el CSS estructural del decorativo, para cargar uno primero y el otro después, con el fin de mejorar 1 segundo de rendering.
ResponderEliminarXD
Es un buen truco. Pensaba que si el JS se puede poner último en el body, con el CSS también funcionaría, y se cargaría después que el HTML. El javascript ayuda mucho cuando hay estilos "selectivos", que se muestran sólo si están cargados (o al menos, encontrados) algunos elementos críticos para un diseño, como las imágenes.
jo jo
EliminarCariño a la city ;-)
si el JS se puede poner último en el body, con el CSS también funcionaría
Con html5 es válido incluir elementos <style> fuera del head,
Y en este blog con este tema es donde tengo el elemento style que incluye las reglas @font-face, al final del body.
Esto junto a la llamada directa al archivo tipográfico en las pruebas que hice en su día tiene un ligero impacto positivo en la velocidad y rendimiento de la página.
Pero creo que mejor que cambiar el valor de "media" y los problemas que se están reportando con esta técnica, sería crearlo con javascript una vez creado el DOM. Incluyendo sólo reglas que afecten al repaint y no al reflow.
Aunque supongo que a estas alturas será una vía ya más que explorada.
Un saludo
Claro y directo, como siempre.
ResponderEliminarEn la página que estoy creando como prueba mientras reaprendo, ya había pensado en la solución de poner el css como primer elemento entre las etiquetas de cierre del body y el html.
Ahora ya lo tengo más claro.
Gracias a ambos y saludos.
Para cargas de forma asíncrona encontré esto:
ResponderEliminarhttps://github.com/filamentgroup
loadCSS
Una función para la carga asíncrona CSS [c] 2014scottjehl, Filamento Group, Inc. bajo licencia MIT
Uso
Coloque el loadCSS función inline en la cabeza de su página (que también puede ser incluido en un archivo de JavaScript externo si prefiere).
Gracias por el enlace, pero creo que te refieres al que ya está incluido en el primer párrafo del cuerpo del artículo.
EliminarUn saludo
La diferencia se nota, la carga va mucho mejor.
ResponderEliminarEl único problema es que no funciona en navegadores antiguos como Safari del iPhone 4, iPad 2 o en Androids de hace 3 años.
Hay forma de que cargue de forma alternativa, parecido al "noscript"
para esos navegadores?
Lo cierto, Alberto es que tras todos los reportes que le hicieron al autor original y el consiguiente aviso por su parte de no usar esta técnica por los problemas detectados no he seguido su evolución.
EliminarUn saludo
Saludos como puedo implementarlo en wordpress?
ResponderEliminarGracias por el aporte
Hola Juan
EliminarEste artículo es del 2015 y lo comienzo con un aviso o advertencia junto a los enlaces al original:
"Haz el favor de consultar el original para estar al tanto de las revisiones y las actualizaciones que pueda hacer su autor."
Advertencia que en este caso es de vital importancia, pues, como ya indiqué en mi respuesta al comentario anterior al tuyo, el autor original ya desaconsejaba el uso de esta técnica.
Si estás buscando experimentar con la carga de webfonts quizás te interese este artículo:
Minimun & simple webfont loader
Un saludo
No puedo expresar suficiente gratitud, jaj es el único que me ha resuelto el dichoso problema en 2 días q llevo buscando en la internet. Gracias miles :D
ResponderEliminar