En este codelab, implementarás la recuperación previa de dos maneras: con <link rel="prefetch">
y con el encabezado Link
de HTTP.
La app de ejemplo es un sitio web que tiene una página de destino promocional con un descuento especial para la camiseta más vendida de la tienda. Dado que la página de destino vincula a un solo producto, es seguro suponer que un alto porcentaje de usuarios navegará a la página de detalles del producto. Esto hace que la página del producto sea un excelente candidato para la recuperación previa en la página de destino.
Cómo medir el rendimiento
Primero, establece el rendimiento de referencia:
- Presiona "Control + Mayúsculas + J" (o "Comando + Opción + J" en Mac) para abrir DevTools.
Haga clic en la pestaña Red.
En la lista desplegable Limitación, selecciona Fast 3G para simular un tipo de conexión lenta.
Para cargar la página del producto, haz clic en Comprar ahora en la app de ejemplo.
La página product-details.html
tarda alrededor de 600 ms en cargarse:
Prefetch de la página del producto con <link rel="prefetch">
Para mejorar la navegación, inserta una etiqueta prefetch
en la página de destino para realizar una recuperación previa de la página product-details.html
:
- Agrega el siguiente elemento
<link>
al encabezado del archivoviews/index.html
:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
El atributo as
es opcional, pero se recomienda, ya que ayuda al navegador a establecer los encabezados correctos y determinar si el recurso ya está en la caché. Entre los valores de ejemplo para este atributo, se incluyen los siguientes: document
, script
, style
, font
, image
y otros.
Para verificar que la recuperación previa esté funcionando, haz lo siguiente:
- Presiona "Control + Mayúsculas + J" (o "Comando + Opción + J" en Mac) para abrir DevTools.
Haga clic en la pestaña Red.
En la lista desplegable Limitación, selecciona Fast 3G para simular un tipo de conexión lenta.
Desmarca la casilla de verificación Inhabilitar la memoria caché.
Vuelve a cargar la app.
Ahora, cuando se carga la página de destino, también se carga la página product-details.html
, pero con la prioridad más baja:
La página se mantiene en la caché de HTTP durante cinco minutos, después de lo cual se aplican las reglas normales de Cache-Control
para el documento. En este caso, product-details.html
tiene un encabezado cache-control
con un valor de public, max-age=0
, lo que significa que la página se mantiene durante un total de cinco minutos.
Reevalúa el rendimiento
- Vuelve a cargar la app.
- Para cargar la página del producto, haz clic en Comprar ahora en la app de ejemplo.
Consulta el panel Red. Existen dos diferencias en comparación con el registro de red inicial:
- En la columna Tamaño, se muestra "caché de carga previa", lo que significa que este recurso se recuperó de la caché del navegador en lugar de la red.
- La columna Time muestra que el tiempo que tarda en cargarse el documento ahora es de aproximadamente 10 ms.
Esto representa una reducción de aproximadamente el 98% en comparación con la versión anterior, que tardaba alrededor de 600 ms.
Crédito adicional: Usa prefetch
como mejora progresiva
La carga previa se implementa mejor como una mejora progresiva para los usuarios que navegan con conexiones rápidas. Puedes usar la API de Network Information para verificar las condiciones de la red y, en función de eso, insertar de forma dinámica etiquetas de recuperación previa. De esta manera, puedes minimizar el consumo de datos y ahorrar costos para los usuarios con planes de datos lentos o costosos.
Para implementar la recuperación anticipada adaptable, primero quita la etiqueta <link rel="prefetch">
de views/index.html
:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
Luego, agrega el siguiente código a public/script.js
para declarar una función que inyecte de forma dinámica la etiqueta prefetch
cuando el usuario tenga una conexión rápida:
function injectLinkPrefetchIn4g(url) {
if (window.navigator.connection.effectiveType === '4g') {
//generate link prefetch tag
const linkTag = document.createElement('link');
linkTag.rel = 'prefetch';
linkTag.href = url;
linkTag.as = 'document';
//inject tag in the head of the document
document.head.appendChild(linkTag);
}
}
La función funciona de la siguiente manera:
- Verifica la propiedad effectiveType de la API de Network Information para determinar si el usuario tiene una conexión 4G (o más rápida).
- Si se cumple esa condición, se genera una etiqueta
<link>
conprefetch
como el tipo de sugerencia, se pasa la URL que se realizará en la recuperación previa en el atributohref
y se indica que el recurso es undocument
HTML en el atributoas
. - Por último, inyecta la secuencia de comandos de forma dinámica en el
head
de la página.
A continuación, agrega script.js
a views/index.html
, justo antes de la etiqueta </body>
de cierre:
<body>
...
<script src="/script.js"></script>
</body>
Solicitar script.js
al final de la página garantiza que se cargará y ejecutará después de que se analice y cargue la página.
Para asegurarte de que la recuperación previa no interfiera con los recursos críticos de la página actual, agrega el siguiente fragmento de código para llamar a injectLinkPrefetchIn4g()
en el evento window.load
:
<body>
...
<script src="/script.js"></script>
<script>
window.addEventListener('load', () => {
injectLinkPrefetchIn4g('/product-details.html');
});
</script>
</body>
Ahora, la página de destino realiza una recuperación previa de product-details.html
solo en conexiones rápidas. Para verificarlo, haz lo siguiente:
- Presiona "Control + Mayúsculas + J" (o "Comando + Opción + J" en Mac) para abrir DevTools.
- Haga clic en la pestaña Red.
- En la lista desplegable Limitación, selecciona En línea.
- Vuelve a cargar la app.
Deberías ver product-details.html
en el panel Network:
Para verificar que la página del producto no se cargue previamente en conexiones lentas, sigue estos pasos:
- En la lista desplegable Throttling, selecciona Slow 3G.
- Vuelve a cargar la app.
El panel Network solo debe incluir los recursos de la página de destino sin product-details.html
:
Realiza una recuperación previa de la hoja de diseño para la página del producto con el encabezado Link
de HTTP
El encabezado Link
de HTTP se puede usar para obtener previamente el mismo tipo de recursos que la etiqueta link
. Decidir cuándo usar uno u otro depende principalmente de tus preferencias, ya que la diferencia en el rendimiento es insignificante. En este caso, lo usarás para obtener previamente el CSS principal de la página de productos y, así, mejorar aún más su renderización.
Agrega un encabezado Link
HTTP para style-product.css
en la respuesta del servidor para la página de destino:
- Abre el archivo
server.js
y busca el controladorget()
para la URL raíz:/
. - Agrega la siguiente línea al comienzo del controlador:
app.get('/', function(request, response) {
response.set('Link', '</style-product.css>; rel=prefetch');
response.sendFile(__dirname + '/views/index.html');
});
- Presiona "Control + Mayúsculas + J" (o "Comando + Opción + J" en Mac) para abrir DevTools.
- Haga clic en la pestaña Red.
- Vuelve a cargar la app.
Ahora, style-product.css
se recupera previamente con la prioridad más baja después de que se carga la página de destino:
Para navegar a la página del producto, haz clic en Comprar ahora. Consulta el panel Red:
El archivo style-product.css
se recuperó de la "caché de recuperación previa" y tardó solo 12 ms en cargarse.