Optimiza la carga de recursos

En el módulo anterior, se introdujeron algunas teorías detrás de la ruta de acceso de renderización crítica exploramos, y cómo los recursos de bloqueo de renderización y de analizadores pueden retrasar un la renderización inicial de la página. Ahora que comprendes parte de la teoría está listo para aprender algunas técnicas para optimizar los costos la ruta de acceso de renderización.

Cuando se carga una página, se hace referencia a muchos recursos en su HTML que proporcionan un página con su apariencia y diseño a través de CSS, así como su interactividad a través de JavaScript. En este módulo, varios conceptos importantes relacionados con se explican estos recursos y cómo afectan el tiempo de carga de una página.

Bloqueo de renderización

Como se analizó en el módulo anterior, CSS es un recurso que render-blocking. ya que impide que el navegador renderice contenido hasta que se aplique el modelo de objetos CSS. (CSSOM). El navegador bloquea la representación para evitar que se Flash de Contenido sin estilo (FOUC), que no es deseable desde el punto de vista de la experiencia del usuario.

En el video anterior, hay un breve FOUC donde puedes ver la página sin cualquier estilo. Posteriormente, todos los estilos se aplican una vez que el CSS de la página se haya terminado de cargarse desde la red y la versión sin estilo de la página reemplazarse de inmediato por la versión con estilo.

En términos generales, un FOUC es algo que normalmente no ves, pero el concepto es importante comprenderlos para que sepas por qué el navegador bloquea la renderización. de la página hasta que se descargue y aplique CSS a la página. Bloqueo de renderización no es necesariamente indeseable, pero sí debe minimizar su duración manteniendo tu CSS optimizado.

Bloqueo del analizador

Un recurso de bloqueo del analizador interrumpe el analizador HTML, como un <script>. sin atributos async ni defer. Cuando el analizador encuentra <script>, el navegador debe evaluar y ejecutar la secuencia de comandos antes analizar el resto del HTML. Esto es intencional, ya que los guiones acceder al DOM ni modificarlo durante un tiempo mientras aún se estaba construyendo.

<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>

Cuando usas archivos JavaScript externos (sin async ni defer), el analizador desde que se descubre el archivo hasta que se descarga, analiza y ejecutado. Cuando usas JavaScript intercalado, el analizador también se bloquea de manera similar hasta que se analiza y ejecuta la secuencia de comandos intercalada.

El escáner de precarga

El escáner de precarga es una optimización del navegador en forma de código HTML secundario. analizador que escanea la respuesta HTML sin procesar para encontrar y recuperar especulativamente recursos antes de que el analizador de HTML principal los descubra. Para ejemplo, el escáner de precarga permitiría que el navegador empezara a descargar una recurso especificado en un elemento <img>, incluso cuando el analizador de HTML está bloqueado y, a su vez, recuperar y procesar recursos como CSS y JavaScript.

Para aprovechar el escáner de precarga, se deben incluir los recursos esenciales en el lenguaje de marcado HTML enviado por el servidor. Los siguientes patrones de carga de recursos se no es detectable para el escáner de precarga:

  • Imágenes cargadas por CSS con la propiedad background-image. Estas imágenes las referencias están en CSS, y el escáner de precarga no puede descubrirlas.
  • Secuencias de comandos cargadas de forma dinámica en forma de lenguaje de marcado de elementos <script> insertado en el DOM con JavaScript o con módulos cargados con import() dinámico.
  • HTML renderizado en el cliente mediante JavaScript. Este lenguaje de marcado se incluye en cadenas en recursos de JavaScript y que no es detectable por la precarga de Google.
  • Declaraciones de @import de CSS.

Todos estos patrones de carga de recursos son recursos de detección tardía y, por lo tanto, no se benefician del escáner de precarga. Evítalos siempre que sea posible. Si No es posible evitar esos patrones. Sin embargo, tal vez pueda utilizar Sugerencia preload para evitar demoras en el descubrimiento de recursos.

CSS

CSS determina la presentación y el diseño de una página. Como se describió anteriormente, CSS es un recurso que bloquea la renderización, por lo que la optimización de CSS podría implicar en el tiempo de carga general de la página.

Reducción

La reducción de archivos CSS reduce el tamaño de los recursos CSS, lo que los convierte más rápido para descargarlos. Esto se logra principalmente quitando contenido de un archivo CSS de origen, como espacios y otros caracteres invisibles, y salida el resultado a un archivo recién optimizado:

/* Unminified CSS: */

/* Heading 1 */
h1 {
  font-size: 2em;
  color: #000000;
}

/* Heading 2 */
h2 {
  font-size: 1.5em;
  color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}

En su forma más básica, la reducción de CSS es una optimización eficaz que podría mejorar el FCP de tu sitio web y, tal vez, incluso el LCP en algunos casos. Herramientas como agrupadores pueden realizar automáticamente esta optimización en la producción. compilaciones.

Quita los elementos CSS que no se usen

Antes de procesar cualquier contenido, el navegador debe descargarlo y analizarlo las hojas de estilo. El tiempo necesario para completar el análisis también incluye los estilos que no están en uso en la página actual. Si usas un agrupador que combina todos los CSS recursos en un solo archivo, es probable que los usuarios descarguen más CSS que necesario para renderizar la página actual.

Para descubrir los elementos CSS que no se usan en la página actual, utiliza la herramienta Cobertura de Chrome. Herramientas para desarrolladores.

Captura de pantalla de la herramienta de cobertura en las Herramientas para desarrolladores de Chrome. En el panel inferior, se selecciona un archivo CSS, que muestra una cantidad considerable de CSS que el diseño de página actual no usa.
La herramienta de cobertura de las Herramientas para desarrolladores de Chrome es útil para detectar CSS (y JavaScript) sin usar en la página actual. Se puede usar para dividir archivos CSS en varios recursos para cargarlos en diferentes páginas, a diferencia del enviar un paquete de CSS mucho más grande que puede retrasar la representación de la página.

Quitar el CSS sin usar tiene un efecto doble: además de reducir la descarga tiempo, optimizarás la construcción del árbol de renderización, ya que el navegador necesita procesar menos reglas de CSS.

Evita las declaraciones @import de CSS

Si bien puede parecer conveniente, debes evitar las declaraciones @import en CSS:

/* Don't do this: */
@import url('style.css');

Al igual que el elemento <link> funciona en HTML, la declaración @import en CSS te permite importar un recurso de CSS externo desde una hoja de estilo. El La mayor diferencia entre estos dos enfoques es que el elemento HTML <link> es parte de la respuesta HTML y, por lo tanto, se descubre mucho antes que un archivo descargado mediante una declaración @import.

Esto se debe a que, para que una declaración @import sea el archivo CSS que lo contiene primero se debe descargar. Esta genera lo que se conoce como una cadena de solicitudes que, en el caso de CSS, retrasa cuánto tarda una página en renderizarse inicialmente. Otro inconveniente es que las hojas de estilo que se cargan con una declaración @import no pueden ser detectadas por el y, por lo tanto, convertirse en recursos que bloquean el procesamiento con descubrimiento tardío.

<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">

En la mayoría de los casos, puedes reemplazar el @import con un elemento <link rel="stylesheet">. Los elementos <link> permiten usar las hojas de estilo descargar al mismo tiempo y reduce el tiempo de carga general, a diferencia del @import que descargan hojas de estilo consecutivamente.

CSS crítico intercalado

El tiempo que lleva descargar archivos CSS puede aumentar el FCP de una página. Integración estilos críticos en el documento <head> elimina la solicitud de red de un recurso de CSS y, cuando se hace correctamente, pueden mejorar los tiempos de carga iniciales cuando un la caché del navegador del usuario no está preparada. El archivo CSS restante se puede cargar. de forma asíncrona, o bien se agregan al final del elemento <body>.

<head>
  <title>Page Title</title>
  <!-- ... -->
  <style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
  <!-- Other page markup... -->
  <link rel="stylesheet" href="non-critical.css">
</body>

La desventaja de insertar una gran cantidad de CSS agrega más bytes a la capa inicial Respuesta HTML. Debido a que los recursos HTML a menudo no se pueden almacenar en caché por mucho tiempo, o en todo esto significa que la CSS intercalada no se almacena en caché para páginas posteriores que puedan usar el mismo CSS en las hojas de estilo externas. Prueba y mide el tráfico de tu página y el rendimiento para asegurarse de que las compensaciones valgan el esfuerzo.

Demostraciones de CSS

JavaScript

JavaScript impulsa la mayor parte de la interactividad en la Web, pero tiene un costo. Si envías demasiado código JavaScript, es posible que tu página web tarde en responder durante la página. de carga de trabajo e incluso pueden causar problemas de respuesta que retrasen las interacciones lo cual puede ser frustrante para los usuarios.

JavaScript que bloquea la renderización

Cuando cargues elementos <script> sin los atributos defer o async, el navegador bloquea el análisis y la renderización hasta que la secuencia de comandos se descargue, analice y ejecutado. De manera similar, las secuencias de comandos intercaladas bloquean el analizador hasta que se analiza la secuencia de comandos y ejecutado.

async en comparación con defer

async y defer permiten que se carguen secuencias de comandos externas sin bloquear el HTML. analizador, mientras que las secuencias de comandos (incluidas las intercaladas) con type="module" se aplaza automáticamente. Sin embargo, async y defer tienen algunas diferencias que es importante comprender.

Representación de varios mecanismos de carga de secuencias de comandos, todos detallan los roles de analizador, recuperación y ejecución en función de varios atributos utilizados, como async, defer, type=&#39;module&#39; y una combinación de los tres.
Fuente: https://html.spec.whatwg.org/multipage/scripting.html
.

Las secuencias de comandos cargadas con async se analizan y se ejecutan de inmediato una vez que se descargan. mientras que las secuencias de comandos cargadas con defer se ejecutan cuando el análisis del documento HTML se finalizado: Esto ocurre al mismo tiempo que el evento DOMContentLoaded del navegador. Además, las secuencias de comandos de async pueden ejecutarse desordenadas, mientras que las secuencias de comandos defer se ejecuten en el orden en que aparecen en el lenguaje de marcado.

Renderización del cliente

En general, debes evitar el uso de JavaScript para procesar cualquier contenido crítico o una elemento LCP de una página. Esto se conoce como renderización del cliente y es una técnica se usan ampliamente en aplicaciones de una sola página (SPA).

El lenguaje de marcado renderizado por JavaScript elude el escáner de carga previa, ya que los recursos incluidos en el lenguaje de marcado renderizado por el cliente no son detectables. Esta podría retrasar la descarga de recursos cruciales, como una imagen LCP. El navegador solo comienza la descarga de la imagen LCP después de que se ejecuta la secuencia de comandos y se agrega el elemento al DOM. A su vez, la secuencia de comandos solo puede ejecutarse descubierto, descargado y analizado. Esto se conoce como solicitud crítica de la cadena y deben evitarse.

Además, es más probable que el lenguaje de marcado con JavaScript genere tareas largas que el lenguaje de marcado descargado desde el servidor en respuesta a una navegación para cada solicitud. El uso extensivo del procesamiento de HTML del cliente puede afectar negativamente latencia de interacción. Esto es especialmente cierto en los casos en que el DOM de una página es muy grande, lo que activa un trabajo de renderización significativo cuando JavaScript modifica el DOM.

Reducción

Al igual que CSS, minificar JavaScript reduce el tamaño de archivo de un recurso de secuencia de comandos. Esto puede generar descargas más rápidas, lo que permitirá que el navegador pase a la de análisis y compilación de JavaScript con mayor rapidez.

Además, la reducción de JavaScript va un paso más allá otros recursos, como los CSS. Cuando se reduce JavaScript, no solo se quita espacios, pestañas y comentarios, pero símbolos en la fuente JavaScript están acortados. Este proceso a veces se conoce como uglificación. Para Para ver la diferencia, toma el siguiente código fuente de JavaScript:

// Unuglified JavaScript source code:
export function injectScript () {
  const scriptElement = document.createElement('script');
  scriptElement.src = '/js/scripts.js';
  scriptElement.type = 'module';

  document.body.appendChild(scriptElement);
}

Cuando se uglifica el código fuente de JavaScript anterior, el resultado puede verse algo como el siguiente fragmento de código:

// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}

En el fragmento anterior, puedes ver que la variable legible por scriptElement en la fuente se abrevia como t. Cuando se aplica en una gran conjunto de secuencias de comandos, el ahorro puede ser bastante significativo, sin afectar las funciones que proporciona el código JavaScript de producción de un sitio web.

Si usas un agrupador para procesar el código fuente de tu sitio web, suele hacerse automáticamente para las compilaciones de producción. Uglificadores, como Terser, por ejemplo, también son altamente configurables, lo que permite ajustar la agresividad del algoritmo de uglificación para lograr el máximo ahorro. Sin embargo, los valores predeterminados de cualquier herramienta de uglificación suelen ser suficientes para ejecutar un ataque. encontrar el equilibrio adecuado entre tamaño de salida y preservación de capacidades.

Demostraciones de JavaScript

Ponga a prueba sus conocimientos

¿Cuál es la mejor manera de cargar varios archivos CSS en el navegador?

La declaración @import de CSS
Varios elementos <link>

¿Qué hace el escáner de precarga del navegador?

Detecta elementos <link rel="preload"> en un recurso HTML.
Es un analizador de HTML secundario que examina el lenguaje de marcado sin procesar para detectar recursos antes de que lo haga el analizador de DOM para descubrirlos antes.

¿Por qué el navegador bloquea temporalmente el análisis de HTML de forma predeterminada cuando descargando recursos de JavaScript?

Porque las secuencias de comandos pueden modificar el DOM o acceder de alguna manera al DOM.
Porque evaluar JavaScript es una tarea con uso intensivo de CPU y pausar El análisis de HTML le da más ancho de banda a la CPU para terminar de cargar las secuencias de comandos.
Para evitar destellos de contenido sin estilo (FOUC).

A continuación: Ayuda al navegador con sugerencias de recursos

Ahora que sabes cómo controlar los recursos cargados en el elemento <head>, afectan la carga inicial de la página y varias métricas, es hora de avanzar. En la próxima se exploran las sugerencias de recursos y cómo pueden brindarte sugerencias útiles para el navegador para comenzar a cargar recursos y abrir conexiones a orígenes cruzados servidores antes que el navegador sin ellos.