En este codelab, implementarás la carga previa de dos maneras: con <link rel="prefetch">
y con el encabezado HTTP Link
.
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 los usuarios navegará a la página de detalles del producto. Esto hace que la página del producto sea un gran candidato para la carga previa en la página de destino.
Cómo medir el rendimiento
Primero, establece el rendimiento de referencia:
- Haz clic en Remix to Edit para que el proyecto sea editable.
- Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa .
- 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 Restricción, selecciona 3G rápido 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:
Cómo realizar la precarga 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 obtener la página product-details.html
de antemano:
- Agrega el siguiente elemento
<link>
al principio 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. Ayuda al navegador a establecer los encabezados correctos y determinar si el recurso ya está en la caché. Algunos valores de ejemplo para este atributo son: document
, script
, style
, font
, image
y otros.
Para verificar que la carga previa funcione, haz lo siguiente:
- Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa .
- 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 Restricción, selecciona 3G rápido para simular un tipo de conexión lenta.
Desmarca la casilla de verificación Inhabilitar la 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 los cuales 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 conserva durante un total de cinco minutos.
Vuelve a evaluar 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:
- La columna Tamaño 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 Tiempo muestra que el tiempo que tarda en cargarse el documento ahora es de alrededor de 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 etiquetas de precarga de forma dinámica. De esta manera, puedes minimizar el consumo de datos y ahorrar costos para los usuarios que tienen planes de datos lentos o costosos.
Para implementar la carga previa adaptativa, 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 recuperará previamente en el atributohref
y se indica que el recurso es undocument
HTML en el atributoas
. - Por último, inserta 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 cargue y ejecute después de que se analice y cargue la página.
Para asegurarte de que la carga 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>
La página de destino ahora realiza la carga previa de product-details.html
solo en conexiones rápidas. Para verificar lo siguiente:
- Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa .
- 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 Restricción, selecciona En línea.
- Vuelve a cargar la app.
Deberías ver product-details.html
en el panel Red:
Para verificar que la página del producto no se precargue en conexiones lentas, sigue estos pasos:
- En la lista desplegable Limitación, selecciona 3G lento.
- Vuelve a cargar la app.
El panel Red debe incluir solo los recursos de la página de destino sin product-details.html
:
Precarga la hoja de estilo de la página del producto con el encabezado HTTP Link
El encabezado HTTP Link
se puede usar para recuperar previamente el mismo tipo de recursos que la etiqueta link
. Decidir cuándo usar uno o el otro depende principalmente de tu preferencia, ya que la diferencia en el rendimiento es insignificante. En este caso, lo usarás para recuperar previamente el CSS principal de la página del producto y mejorar aún más su renderización.
Agrega un encabezado HTTP Link
para style-product.css
en la respuesta del servidor de la página de destino:
- Abre el archivo
server.js
y busca el controladorget()
de 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');
});
- Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa .
- 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 obtiene 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 recupera de la "caché de precarga" y solo tardó 12 ms en cargarse.