Carga previa en app create-react-app con Quicklink

Addy Osmani
Addy Osmani
Anton Karlovskiy
Anton Karlovskiy
Demián Renzulli
Demián Renzulli

En este codelab, se muestra cómo implementar la biblioteca Quicklink en una demostración de React SPA para demostrar cómo la carga previa acelera las navegaciones posteriores.

Medir

Antes de agregar optimizaciones, siempre se recomienda analizar el estado actual de la aplicación.

  • Haz clic en Remix para editar para que el proyecto se pueda editar.
  • Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa pantalla completa

El sitio web es una demostración sencilla compilada con create-react-app.

Completa las siguientes instrucciones en la pestaña nueva que acabas de abrir:

  1. Presiona `Control + Mayúsculas + J` (o `Command + Option + J` en Mac) para abrir Herramientas para desarrolladores.
  2. Haga clic en la pestaña Red.
  3. Selecciona la casilla de verificación Inhabilitar caché.
  4. En la lista desplegable Limitación, selecciona 3G rápida para simular un tipo de conexión lenta.
  5. Vuelve a cargar la app.
  6. Escribe chunk en el cuadro de texto Filtro para ocultar los recursos que no incluyan chunk en su nombre.

Panel Network que muestra los fragmentos de la página principal.

El sitio usa división de código basada en rutas, gracias a la cual solo se solicita el código necesario al principio.

  1. Borra las solicitudes de red en Herramientas para desarrolladores.
  2. En la app, haz clic en el vínculo Blog para navegar a esa página.

Los fragmentos de JS y CSS de la ruta nueva se cargan para representar la página.

Panel Network que muestra los fragmentos de la página del blog.

A continuación, implementarás Quicklink en este sitio para que esos fragmentos puedan cargarse previamente en la página principal y agilizar la navegación.

Esto te permite combinar lo mejor de ambas técnicas:

  • La división de código basada en la ruta le indica al navegador que cargue solo los fragmentos necesarios con una prioridad más alta cuando se cargue la página.
  • La carga previa indica al navegador que cargue los fragmentos de los vínculos dentro del viewport con la prioridad más baja, durante el tiempo de inactividad del navegador.

Configurar webpack-route-manifest

El primer paso es instalar y configurar webpack-route-manifest, un complemento de webpack que te permite generar un archivo de manifiesto asociando rutas con los fragmentos correspondientes.

Por lo general, tendrás que instalar la biblioteca, pero ya lo hicimos por ti. Este es el comando que deberás ejecutar:

npm install webpack-route-manifest --save-dev

config-overrides.js es un archivo ubicado en el directorio raíz de tu proyecto, en el que puedes anular el comportamiento existente de la configuración de webpack, sin tener que expulsar el proyecto.

  • Para ver la fuente, presiona Ver fuente.

Abre config-overrides.js para editarlo y agrega la dependencia webpack-route-manifest al comienzo del archivo:

const path = require('path');
const RouteManifest = require('webpack-route-manifest');

A continuación, configura el complemento webpack-route-manifest agregando lo siguiente código al final de config-overrides.js:

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: {
      '@assets': `${path.resolve(__dirname, 'src/assets')}`,
      '@pages': `${path.resolve(__dirname, 'src/pages')}`,
      '@components': `${path.resolve(__dirname, 'src/components')}`,
    },
  };

  config.plugins.push(
    new RouteManifest({
      minify: true,
      filename: 'rmanifest.json',
      routes(str) {
        let out = str.replace('@pages', '').toLowerCase();
        if (out === '/article') return '/blog/:title';
        if (out === '/home') return '/';
        return out;
      },
    }),
  );

  return config;
};

El código nuevo hace lo siguiente:

  • config.resolve declara variables con las rutas internas a páginas, recursos y componentes.
  • config.plugins.push() crea un objeto RouteManifest y le pasa la configuración para que se pueda generar el archivo rmanifest.json en función de las rutas y los fragmentos del sitio.

Se generará el archivo manifest.json y estará disponible en https://site_url/rmanifest.json.

En este punto, necesitarías instalar la biblioteca Quicklink en tu proyecto. Para simplificar, ya lo agregamos al proyecto. Este es el comando que deberás ejecutar:

npm install --save quicklink

Abre src/components/App/index.js para editarlo.

Primero, importa el componente de pedido superior (HOC) de Quicklink:

import React, { lazy, Suspense } from 'react';
import { Route } from 'react-router-dom';

import Footer from '@components/Footer';
import Hero from '@components/Hero';
import style from './index.module.css';
import { withQuicklink } from 'quicklink/dist/react/hoc.js';

const Home = lazy(() => import(/* webpackChunkName: "home" */ '@pages/Home'));
const About = lazy(() => import(/* webpackChunkName: "about" */ '@pages/About'));
const Article = lazy(() => import(/* webpackChunkName: "article" */ '@pages/Article'));
const Blog = lazy(() => import(/* webpackChunkName: "blog" */ '@pages/Blog'));

A continuación, crea un objeto options después de la declaración de variable Blog para usarlo como argumento cuando llames a quicklink:

const options = {
    origins: []
};

Por último, une cada ruta con el componente de orden superior withQuicklink() y pásale un parámetro options y el componente de destino de esa ruta:

const App = () => (
  <div className={style.app}>
    <Hero />
    <main className={style.wrapper}>
      <Suspense fallback={<div>Loading...</div>}>
        <Route path="/" exact component={withQuicklink(Home, options)} />
        <Route path="/blog" exact component={withQuicklink(Blog, options)} />
        <Route
          path="/blog/:title"
          component={withQuicklink(Article, options)}
        />
        <Route path="/about" exact component={withQuicklink(About, options)} />
      </Suspense>
    </main>
    <Footer />
  </div>
);

El código anterior indica que se soliciten previamente fragmentos para las rutas unidas con withQuicklink(), cuando el vínculo aparece en la vista.

Volver a medir

Repite los primeros 6 pasos de la función Medir. Todavía no navegues a la página del blog.

Cuando se carga la página principal, se cargan los fragmentos de esa ruta. Después, Quicklink realiza una carga previa de los fragmentos de la ruta para los vínculos en la ventana de visualización:

Panel de red que muestra los fragmentos de carga previa de la página principal.

Esos fragmentos se solicitan con la prioridad más baja y sin bloquear la página.

Siguiente:

  1. Vuelve a borrar el registro de red.
  2. Inhabilita la casilla de verificación Inhabilitar caché.
  3. Haz clic en el vínculo Blog para navegar a esa página.

Panel Network que muestra la página del blog con fragmentos extraídos de la caché.

La columna Size indica que estos fragmentos se recuperaron de la "memoria caché con carga previa", en lugar de la red. La carga de estos fragmentos sin un Quicklink tomó aproximadamente 580 ms. Ahora, el uso de la biblioteca tarda 2 ms, lo que representa una reducción del 99% .