No te comprometas con el escáner de precarga del navegador

Descubre qué es el escáner de carga previa del navegador, cómo ayuda al rendimiento y cómo puedes evitarlo.

Un aspecto que se pasa por alto a la hora de optimizar la velocidad de la página es conocer un poco sobre los elementos internos del navegador. Los navegadores realizan ciertas optimizaciones para mejorar el rendimiento de formas que nosotros, como desarrolladores, no podemos, pero solo mientras esas optimizaciones no se frustren de forma involuntaria.

Una optimización interna del navegador que debes comprender es el escáner de carga previa del navegador. En esta publicación, se explicará cómo funciona el escáner de carga previa y, lo que es más importante, cómo evitar que se interponga en tu camino.

¿Qué es un escáner de carga previa?

Cada navegador tiene un analizador de HTML principal que tokeniza el lenguaje de marcado sin procesar y lo procesa en un modelo de objetos. Todo esto continúa de forma alegre hasta que el analizador se detiene cuando encuentra un recurso de bloqueo, como una hoja de estilo cargada con un elemento <link> o una secuencia de comandos cargada con un elemento <script> sin un atributo async o defer.

Diagrama del analizador de HTML.
Figura 1: Un diagrama de cómo se puede bloquear el analizador de HTML principal del navegador. En este caso, el analizador encuentra un elemento <link> para un archivo CSS externo, lo que impide que el navegador analice el resto del documento (o incluso renderice parte de él) hasta que se descargue y analice el CSS.

En el caso de los archivos CSS, se bloquea la renderización para evitar un destello de contenido sin diseño (FOUC), que es cuando se puede ver brevemente una versión sin diseño de una página antes de que se le apliquen los diseños.

La página principal de web.dev sin diseño (izquierda) y con diseño (derecha).
Figura 2: Un ejemplo simulado de la AUA. A la izquierda, se muestra la página principal de web.dev sin estilos. A la derecha, se muestra la misma página con los estilos aplicados. El estado sin diseño puede ocurrir en un instante si el navegador no bloquea la renderización mientras se descarga y procesa una hoja de estilo.

El navegador también bloquea el análisis y la renderización de la página cuando encuentra elementos <script> sin un atributo defer o async.

El motivo es que el navegador no puede saber con certeza si una secuencia de comandos determinada modificará el DOM mientras el analizador de HTML principal aún está haciendo su trabajo. Por este motivo, es una práctica común cargar el código JavaScript al final del documento para que los efectos del análisis y la renderización bloqueados sean marginales.

Estos son buenos motivos por los que el navegador debe bloquear el análisis y la renderización. Sin embargo, no es conveniente bloquear ninguno de estos pasos importantes, ya que pueden retrasar el descubrimiento de otros recursos importantes. Afortunadamente, los navegadores hacen todo lo posible para mitigar estos problemas a través de un analizador de HTML secundario llamado escáner de precarga.

Diagrama del analizador de HTML principal (izquierda) y del escáner de carga previa (derecha), que es el analizador de HTML secundario.
Figura 3: Un diagrama que muestra cómo funciona el escáner de carga previa en paralelo con el analizador de HTML principal para cargar recursos de forma especulativa. Aquí, el analizador de HTML principal se bloquea cuando carga y procesa CSS antes de que pueda comenzar a procesar el lenguaje de marcado de imagen en el elemento <body>, pero el escáner de carga previa puede mirar hacia adelante en el lenguaje de marcado sin procesar para encontrar ese recurso de imagen y comenzar a cargarlo antes de que se desbloquee el analizador de HTML principal.

El rol de un escáner de carga previa es especulativo, lo que significa que examina el marcado sin procesar para encontrar recursos que se puedan recuperar de forma oportunista antes de que el analizador de HTML principal los descubra.

Cómo saber cuándo está funcionando el escáner de carga previa

El escáner de carga previa existe porque se bloqueó la renderización y el análisis. Si estos dos problemas de rendimiento nunca hubieran existido, el escáner de carga previa no sería muy útil. La clave para determinar si una página web se beneficia del escáner de carga previa depende de estos fenómenos de bloqueo. Para ello, puedes introducir una demora artificial en las solicitudes para averiguar dónde funciona el escáner de carga previa.

Como ejemplo, toma esta página de texto e imágenes básicos con una hoja de estilo. Debido a que los archivos CSS bloquean la renderización y el análisis, se introduce una demora artificial de dos segundos para la hoja de estilo a través de un servicio de proxy. Esta demora permite ver con mayor facilidad en la cascada de red dónde está trabajando el escáner de carga previa.

El gráfico de cascada de red de WebPageTest ilustra una demora artificial de 2 segundos impuesta en la hoja de estilo.
Fig. 4: Un gráfico de cascada de red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. Aunque la hoja de estilo se retrasa artificialmente a través de un proxy dos segundos antes de que comience a cargarse, el escáner de carga previa descubre la imagen que se encuentra más adelante en la carga útil de marcado.

Como puedes ver en la cascada, el escáner de carga previa descubre el elemento <img> incluso mientras se bloquea la renderización y el análisis de documentos. Sin esta optimización, el navegador no puede recuperar elementos de forma oportunista durante el período de bloqueo, y más solicitudes de recursos serían consecutivas en lugar de simultáneas.

Ahora que ya conoces el ejemplo de juguete, veamos algunos patrones del mundo real en los que se puede vencer al escáner de carga previa y qué se puede hacer para solucionarlos.

Secuencias de comandos async insertadas

Supongamos que tienes HTML en tu <head> que incluye JavaScript intercalado como este:

<script>
 
const scriptEl = document.createElement('script');
  scriptEl
.src = '/yall.min.js';

  document
.head.appendChild(scriptEl);
</script>

Las secuencias de comandos insertadas son async de forma predeterminada, por lo que, cuando se inserten, se comportarán como si se les aplicara el atributo async. Esto significa que se ejecutará lo antes posible y no bloqueará la renderización. Suena bien, ¿no? Sin embargo, si supones que este <script> intercalado viene después de un elemento <link> que carga un archivo CSS externo, obtendrás un resultado poco óptimo:

En este gráfico de WebPageTest, se muestra que se derrota el análisis de carga previa cuando se inyecta una secuencia de comandos.
Figura 5: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. La página contiene una sola hoja de estilo y una secuencia de comandos async insertada. El escáner de carga previa no puede descubrir la secuencia de comandos durante la fase de bloqueo de renderización, ya que se inyecta en el cliente.

Veamos qué sucedió aquí:

  1. A los 0 segundos, se solicita el documento principal.
  2. A los 1.4 segundos, llega el primer byte de la solicitud de navegación.
  3. A los 2.0 segundos, se solicitan el CSS y la imagen.
  4. Debido a que el analizador está bloqueado para cargar la hoja de estilo y el código JavaScript intercalado que inserta la secuencia de comandos async aparece después de esa hoja de estilo a los 2.6 segundos, la funcionalidad que proporciona la secuencia de comandos no está disponible tan pronto como podría.

Esto no es lo ideal porque la solicitud de la secuencia de comandos se produce solo después de que se termina de descargar la hoja de estilo. Esto retrasa la ejecución de la secuencia de comandos lo antes posible. Por el contrario, como el elemento <img> se puede detectar en el marcado proporcionado por el servidor, el escáner de carga previa lo descubre.

Entonces, ¿qué sucede si usas una etiqueta <script> normal con el atributo async en lugar de insertar la secuencia de comandos en el DOM?

<script src="/yall.min.js" async></script>

Este es el resultado:

Cascada de red de WebPageTest que muestra cómo el escáner de carga previa del navegador aún puede detectar una secuencia de comandos asíncrona cargada con el elemento de secuencia de comandos HTML, a pesar de que el analizador de HTML principal del navegador está bloqueado mientras se descarga y procesa una hoja de estilo.
Fig. 6: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. La página contiene una sola hoja de estilo y un solo elemento <script> async. El escáner de carga previa descubre la secuencia de comandos durante la fase de bloqueo de renderización y la carga de forma simultánea con el CSS.

Es posible que te sientas tentado a sugerir que estos problemas se podrían solucionar con rel=preload. Esto funcionaría, pero podría tener algunos efectos secundarios. Después de todo, ¿por qué usar rel=preload para solucionar un problema que se puede evitar si no se inyecta un elemento <script> en el DOM?

Una cascada de WebPageTest que muestra cómo se usa la sugerencia de recursos rel=preload para promover el descubrimiento de una secuencia de comandos insertada asíncrona, aunque de una manera que puede tener efectos secundarios no deseados.
Fig. 7: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. La página contiene una sola hoja de estilo y una secuencia de comandos async insertada, pero la secuencia de comandos async se precarga para garantizar que se descubra antes.

La carga previa “soluciona” el problema aquí, pero presenta un problema nuevo: la secuencia de comandos async en las dos primeras demostraciones, a pesar de cargarse en <head>, se carga con prioridad “Baja”, mientras que la hoja de estilos se carga con prioridad “Más alta”. En la última demostración, en la que se precargó la secuencia de comandos async, la hoja de estilo aún se carga con la prioridad "Más alta", pero la prioridad de la secuencia de comandos se promocionó a "Alta".

Cuando se aumenta la prioridad de un recurso, el navegador le asigna más ancho de banda. Esto significa que, aunque la hoja de estilo tiene la prioridad más alta, la prioridad elevada de la secuencia de comandos puede causar una contención de ancho de banda. Ese podría ser un factor en las conexiones lentas o en los casos en que los recursos son bastante grandes.

La respuesta aquí es sencilla: si se necesita una secuencia de comandos durante el inicio, no la introduzcas en el DOM para evitar el escáner de carga previa. Experimenta según sea necesario con la ubicación de los elementos <script>, así como con atributos como defer y async.

Carga diferida con JavaScript

La carga diferida es un excelente método para conservar datos, que se aplica con frecuencia a las imágenes. Sin embargo, a veces, la carga diferida se aplica de forma incorrecta a las imágenes que están “en la mitad superior de la página”, por así decirlo.

Esto genera posibles problemas con la visibilidad de los recursos en el caso del escáner de carga previa y puede retrasar innecesariamente el tiempo que se tarda en descubrir una referencia a una imagen, descargarla, decodificarla y presentarla. Tomemos como ejemplo este lenguaje de marcado de imagen:

<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

El uso de un prefijo data- es un patrón común en los cargadores diferidos con tecnología de JavaScript. Cuando se desplaza la imagen al viewport, el cargador diferido quita el prefijo data-, lo que significa que, en el ejemplo anterior, data-src se convierte en src. Esta actualización le indica al navegador que recupere el recurso.

Este patrón no es problemático hasta que se aplica a las imágenes que están en el viewport durante el inicio. Debido a que el escáner de carga previa no lee el atributo data-src de la misma manera que lo haría con un atributo src (o srcset), la referencia de la imagen no se descubre antes. Lo que es peor, la imagen no se carga hasta después de que el cargador diferido de JavaScript descargue, compile y ejecute el código.

Gráfico en cascada de la red de WebPageTest que muestra cómo una imagen cargada de forma diferida que se encuentra en el viewport durante el inicio se retrasa necesariamente porque el escáner de carga previa del navegador no puede encontrar el recurso de imagen y solo se carga cuando se carga el código JavaScript necesario para que funcione la carga diferida. La imagen se descubre mucho más tarde de lo que debería.
Figura 8: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. El recurso de imagen se carga de forma diferida innecesariamente, aunque es visible en el viewport durante el inicio. Esto evita el escáner de carga previa y causa una demora innecesaria.

Según el tamaño de la imagen, que puede depender del tamaño del viewport, puede ser un elemento candidato para el procesamiento de imagen con contenido más grande (LCP). Cuando el escáner de carga previa no puede recuperar de forma especulativa el recurso de imagen con anticipación, posiblemente durante el punto en el que los diseños de página bloquean la renderización, el LCP se ve afectado.

La solución es cambiar el marcado de la imagen:

<img src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

Este es el patrón óptimo para las imágenes que se encuentran en el viewport durante el inicio, ya que el escáner de carga previa descubrirá y recuperará el recurso de imagen más rápido.

Gráfico de cascada de red de WebPageTest que muestra una situación de carga para una imagen en la ventana de visualización durante el inicio. La imagen no se carga de forma diferida, lo que significa que no depende de la carga de la secuencia de comandos, por lo que el escáner de carga previa puede detectarla antes.
Figura 9: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. El escáner de carga previa descubre el recurso de imagen antes de que comiencen a cargarse el CSS y el JavaScript, lo que le da al navegador una ventaja para cargarlo.

El resultado de este ejemplo simplificado es una mejora de 100 milisegundos en el LCP en una conexión lenta. Puede que no parezca una gran mejora, pero lo es cuando consideras que la solución es una corrección rápida del marcado y que la mayoría de las páginas web son más complejas que este conjunto de ejemplos. Esto significa que los candidatos de LCP pueden tener que competir por el ancho de banda con muchos otros recursos, por lo que las optimizaciones como esta se vuelven cada vez más importantes.

Imágenes de fondo de CSS

Recuerda que el escáner de precarga del navegador analiza el marcado. No analiza otros tipos de recursos, como CSS, que pueden incluir recuperaciones de imágenes a las que hace referencia la propiedad background-image.

Al igual que el HTML, los navegadores procesan el CSS en su propio modelo de objetos, conocido como CSSOM. Si se descubren recursos externos a medida que se construye el CSSOM, esos recursos se solicitan en el momento del descubrimiento y no por el escáner de carga previa.

Supongamos que el candidato de LCP de tu página es un elemento con una propiedad background-image de CSS. A medida que se cargan los recursos, sucede lo siguiente:

Gráfico de cascada de red de WebPageTest que muestra una página con un candidato de LCP cargado desde CSS con la propiedad background-image. Debido a que la imagen candidata de la LCP está en un tipo de recurso que el escáner de carga previa del navegador no puede examinar, el recurso no se carga hasta que se descarga y procesa el CSS, lo que retrasa el tiempo de pintura de la LCP candidata.
Fig. 10: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. El candidato de LCP de la página es un elemento con una propiedad background-image de CSS (fila 3). La imagen que solicita no comienza a recuperar hasta que el analizador de CSS la encuentra.

En este caso, el escáner de carga previa no se ve afectado tanto como no participa. Aun así, si un candidato de LCP en la página proviene de una propiedad CSS background-image, te recomendamos que precargues esa imagen:

<!-- Make sure this is in the <head> below any
     stylesheets, so as not to block them from loading -->

<link rel="preload" as="image" href="lcp-image.jpg">

Esa sugerencia de rel=preload es pequeña, pero ayuda al navegador a descubrir la imagen antes de lo que lo haría de otra manera:

Gráfico en cascada de la red de WebPageTest que muestra una imagen de fondo CSS (que es el candidato de LCP) que se carga mucho antes debido al uso de una sugerencia rel=preload. El tiempo de LCP mejora en aproximadamente 250 milisegundos.
Fig. 11: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. El candidato de LCP de la página es un elemento con una propiedad background-image de CSS (fila 3). La sugerencia rel=preload ayuda al navegador a descubrir la imagen unos 250 milisegundos antes que sin ella.

Con la sugerencia rel=preload, el candidato de LCP se descubre antes, lo que reduce el tiempo de LCP. Si bien esa sugerencia ayuda a solucionar este problema, la mejor opción puede ser evaluar si tu candidato de LCP de imagen debe cargarse desde CSS. Con una etiqueta <img>, tendrás más control sobre la carga de una imagen adecuada para el viewport y, al mismo tiempo, permitirás que el escáner de carga previa la descubra.

Incorporación de demasiados recursos

La incorporación intercalada es una práctica que coloca un recurso dentro del código HTML. Puedes intercalar hojas de estilo en elementos <style>, secuencias de comandos en elementos <script> y prácticamente cualquier otro recurso con la codificación base64.

Incorporar recursos puede ser más rápido que descargarlos porque no se emite una solicitud independiente para el recurso. Está en el documento y se carga al instante. Sin embargo, existen desventajas significativas:

  • Si no almacenas en caché tu HTML (y no puedes hacerlo si la respuesta HTML es dinámica), los recursos intercalados nunca se almacenan en caché. Esto afecta el rendimiento porque los recursos intercalados no se pueden volver a usar.
  • Incluso si puedes almacenar en caché el HTML, los recursos intercalados no se comparten entre documentos. Esto reduce la eficiencia del almacenamiento en caché en comparación con los archivos externos que se pueden almacenar en caché y reutilizar en un origen completo.
  • Si incorporas demasiado contenido, retrasas el descubrimiento de recursos por parte del escáner de carga previa más adelante en el documento, ya que la descarga de ese contenido adicional incorporado tarda más.

Tomemos esta página como ejemplo. En ciertas condiciones, el candidato de LCP es la imagen en la parte superior de la página, y el CSS está en un archivo separado que carga un elemento <link>. La página también usa cuatro fuentes web que se solicitan como archivos separados del recurso CSS.

Gráfico de cascada de red de WebPageTest de una página con un archivo CSS externo en el que se hace referencia a cuatro fuentes. El escáner de carga previa descubre la imagen candidata del LCP a su debido tiempo.
Fig. 12: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. El candidato de LCP de la página es una imagen cargada desde un elemento <img>, pero el escáner de carga previa lo descubre porque el CSS y las fuentes necesarias para la carga de la página se encuentran en recursos separados, lo que no retrasa el trabajo del escáner de carga previa.

Ahora bien, ¿qué sucede si el CSS y todas las fuentes están intercaladas como recursos base64?

Gráfico de cascada de red de WebPageTest de una página con un archivo CSS externo en el que se hace referencia a cuatro fuentes. El escáner de carga previa se retrasa significativamente en el descubrimiento de la imagen del LCP .
Fig. 13: Gráfico en cascada de la red de WebPageTest de una página web que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. El candidato de LCP de la página es una imagen cargada desde un elemento <img>, pero la incorporación del CSS y sus cuatro recursos de fuente en el " retrasa que el escáner de carga previa descubra la imagen hasta que se descarguen por completo esos recursos.

En este ejemplo, el impacto de la incorporación produce consecuencias negativas para el LCP y para el rendimiento en general. La versión de la página que no incorpora nada pinta la imagen de LCP en aproximadamente 3.5 segundos. La página que incorpora todo no pinta la imagen de LCP hasta después de 7 segundos.

Aquí hay más en juego que solo el escáner de carga previa. Incorporar fuentes no es una buena estrategia porque base64 es un formato ineficiente para recursos binarios. Otro factor en juego es que los recursos de fuentes externas no se descargan, a menos que el CSSOM determine que son necesarios. Cuando esas fuentes se intercalan como base64, se descargan, ya sea que se necesiten para la página actual o no.

¿Podría mejorar la situación una carga previa? Por supuesto. Podrías precargar la imagen del LCP y reducir el tiempo del LCP, pero aumentar tu HTML potencialmente no almacenable en caché con recursos intercalados tiene otras consecuencias negativas para el rendimiento. El primer procesamiento de imagen con contenido (FCP) también se ve afectado por este patrón. En la versión de la página en la que no se intercala nada, el FCP es de aproximadamente 2.7 segundos. En la versión en la que todo está intercalado, el FCP es de alrededor de 5.8 segundos.

Ten mucho cuidado con la incorporación de elementos en el código HTML, en especial los recursos codificados en Base64. En general, no se recomienda, excepto para recursos muy pequeños. Usa la incorporación lo menos posible, ya que incorporar demasiado es jugar con fuego.

Renderiza el marcado con JavaScript del cliente

No hay duda: JavaScript afecta definitivamente la velocidad de la página. Los desarrolladores no solo dependen de ella para proporcionar interactividad, sino que también existe una tendencia a depender de ella para publicar contenido. Esto genera una mejor experiencia para los desarrolladores en algunos aspectos, pero los beneficios para los desarrolladores no siempre se traducen en beneficios para los usuarios.

Un patrón que puede vencer al escáner de carga previa es renderizar el marcado con JavaScript del cliente:

Cascada de red de WebPageTest que muestra una página básica con imágenes y texto renderizados por completo en el cliente en JavaScript. Debido a que el marcado se encuentra dentro de JavaScript, el escáner de carga previa no puede detectar ninguno de los recursos. Además, todos los recursos se retrasan debido al tiempo de procesamiento y red adicional que requieren los frameworks de JavaScript.
Fig. 14: Gráfico en cascada de la red de WebPageTest de una página web renderizada por el cliente que se ejecuta en Chrome en un dispositivo móvil a través de una conexión 3G simulada. Como el contenido se encuentra en JavaScript y depende de un framework para renderizarse, el recurso de imagen en el lenguaje de marcado renderizado por el cliente se oculta al escáner de carga previa. La experiencia equivalente renderizada por el servidor se muestra en la Fig. 9.

Cuando las cargas útiles de marcado se contienen en JavaScript y se renderizan por completo en el navegador, los recursos de ese marcado son invisibles para el escáner de carga previa. Esto retrasa el descubrimiento de recursos importantes, lo que, sin duda, afecta el LCP. En el caso de estos ejemplos, la solicitud de la imagen de la LCP se retrasa significativamente en comparación con la experiencia equivalente renderizada por el servidor que no requiere que aparezca JavaScript.

Esto se aleja un poco del enfoque de este artículo, pero los efectos de renderizar el marcado en el cliente van mucho más allá de derrotar al escáner de carga previa. Por un lado, la incorporación de JavaScript para potenciar una experiencia que no lo requiere introduce un tiempo de procesamiento innecesario que puede afectar la Interaction to Next Paint (INP). Es más probable que la renderización de cantidades extremadamente grandes de marcas en el cliente genere tareas largas en comparación con la misma cantidad de marcas que envía el servidor. El motivo de esto, además del procesamiento adicional que implica JavaScript, es que los navegadores transmiten el marcado desde el servidor y dividen la renderización de manera tal que tiende a limitar las tareas largas. Por otro lado, el marcado renderizado por el cliente se controla como una sola tarea monolítica, lo que puede afectar el INP de una página.

La solución para esta situación depende de la respuesta a esta pregunta: ¿Hay algún motivo por el que el servidor no pueda proporcionar el marcado de tu página en lugar de renderizarlo en el cliente? Si la respuesta es "no", se debe considerar la renderización del servidor (SSR) o el marcado generado de forma estática siempre que sea posible, ya que ayudará al escáner de carga previa a descubrir y recuperar recursos importantes de forma oportunista con anticipación.

Si tu página necesita JavaScript para adjuntar funcionalidad a algunas partes del marcado de la página, puedes hacerlo con SSR, ya sea con JavaScript puro o con hidratación para obtener lo mejor de ambos mundos.

Cómo ayudar al escáner de carga previa a ayudarte

El escáner de carga previa es una optimización del navegador muy eficaz que ayuda a que las páginas se carguen más rápido durante el inicio. Si evitas los patrones que anulan su capacidad de descubrir recursos importantes con anticipación, no solo simplificarás el desarrollo, sino que también crearás mejores experiencias del usuario que generarán mejores resultados en muchas métricas, incluidas algunas métricas web esenciales.

En resumen, estos son los aspectos que debes tener en cuenta después de leer esta publicación:

  • El escáner de precarga del navegador es un analizador de HTML secundario que escanea antes que el principal si está bloqueado para descubrir de forma oportunista los recursos que puede recuperar antes.
  • El escáner de carga previa no puede detectar los recursos que no están presentes en el marcado que proporciona el servidor en la solicitud de navegación inicial. Entre las formas en que se puede evitar el escáner de carga previa, se incluyen las siguientes:
    • Inyección de recursos en el DOM con JavaScript, ya sean secuencias de comandos, imágenes, hojas de estilo o cualquier otro elemento que sea más conveniente en la carga útil de lenguaje de marcado inicial del servidor
    • Carga diferida de imágenes o iframes de la mitad superior de la página con una solución de JavaScript
    • Renderización de marcas en el cliente que pueden contener referencias a subrecursos de documentos con JavaScript
  • El escáner de precarga solo analiza HTML. No examina el contenido de otros recursos, en particular, el CSS, que puede incluir referencias a recursos importantes, incluidos los candidatos de LCP.

Si, por algún motivo, no puedes evitar un patrón que afecte negativamente la capacidad del escáner de carga previa para acelerar el rendimiento de la carga, considera la sugerencia de recursos rel=preload. Si usas rel=preload, prueba en herramientas de lab para asegurarte de que te brinde el efecto deseado. Por último, no precargues demasiados recursos, ya que, si priorizas todo, no lo harás.

Recursos

Imagen hero de Unsplash, por Mohammad Rahmani .