Acelera la navegación en React con Quicklink

Precarga automáticamente los vínculos en el viewport con el vínculo rápido para aplicaciones de una sola página de React.

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

La carga previa es una técnica que permite acelerar las navegaciones, ya que se descargan los recursos para la página siguiente con anticipación. Quicklink es una biblioteca que te permite implementar esta técnica a gran escala, ya que precarga automáticamente los vínculos a medida que aparecen en la vista.

En las apps de varias páginas, la biblioteca precarga documentos (p. ej., /article.html) para los vínculos en el viewport, de modo que, cuando el usuario haga clic en estos vínculos, se puedan recuperar de la caché de HTTP.

Por lo general, las apps de una sola página usan una técnica llamada división de código basada en rutas. Esto permite que el sitio cargue el código de una ruta determinada solo cuando el usuario navega a ella. Estos archivos (JS y CSS) suelen denominarse "fragmentos".

Dicho esto, en estos sitios, en lugar de almacenar en caché los documentos, los mayores aumentos de rendimiento provienen de almacenar en caché estos fragmentos antes de que la página los necesite.

Lograr esto presenta algunos desafíos:

  • No es trivial determinar qué fragmentos (p. ej., article.chunk.js) están asociados con una ruta determinada (p. ej., /article) antes de llegar a ella.
  • No se pueden predecir los nombres de URL finales de estos fragmentos, ya que los empaquetadores de módulos modernos suelen usar hash a largo plazo para el control de versiones (p. ej., article.chunk.46e51.js).

En esta guía, se explica cómo Quicklink resuelve estos desafíos y te permite lograr la carga previa a gran escala en apps de una sola página de React.

Determina los fragmentos asociados con cada ruta

Uno de los componentes principales de quicklink es webpack-route-manifest, un complemento de webpack que te permite generar un diccionario JSON de rutas y fragmentos. Esto permite que la biblioteca sepa qué archivos necesitará cada ruta de la aplicación y los precargue a medida que las rutas aparecen en la vista.

Después de integrar el complemento con el proyecto, se generará un archivo de manifiesto JSON que asociará cada ruta con sus fragmentos correspondientes:

{
  '/about': [
    {
      type: 'style',
      href: '/static/css/about.f6fd7d80.chunk.css',
    },
    {
      type: 'script',
      href: '/static/js/about.1cdfef3b.chunk.js',
    },
  ],
  '/blog': [
    {
      type: 'style',
      href: '/static/css/blog.85e80e75.chunk.css',
    },
    {
      type: 'script',
      href: '/static/js/blog.35421503.chunk.js',
    },
  ],
}

Este archivo de manifiesto se puede solicitar de dos maneras:

  • Por URL, p. ej., https://site_url/rmanifest.json.
  • A través del objeto window, en window.__rmanifest.

Carga previa de fragmentos para rutas dentro del viewport

Una vez que el archivo de manifiesto esté disponible, el siguiente paso es instalar Quicklink ejecutando npm install quicklink.

Luego, se puede usar el componente de orden superior (HOC) withQuicklink() para indicar que se debe recuperar previamente una ruta determinada cuando el vínculo ingresa a la vista.

El siguiente código pertenece a un componente App de una app de React que renderiza un menú superior con cuatro vínculos:

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

Para indicarle a Quicklink que estas rutas deben precargarse a medida que aparecen en la vista, haz lo siguiente:

  1. Importa el HOC quicklink al comienzo del componente.
  2. Une cada ruta con el HOC withQuicklink() y pásale el componente de página y el parámetro de opciones.
const options = {
  origins: [],
};
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 HOC de withQuicklink() usa la ruta de acceso de la ruta como clave para obtener sus fragmentos asociados a partir de rmanifest.json. En el fondo, a medida que los vínculos aparecen en la vista, la biblioteca inserta una etiqueta <link rel="prefetch"> en la página para cada fragmento para que se puedan recuperar previamente. El navegador solicitará los recursos previamente obtenidos con la prioridad más baja y los mantendrá en la caché de HTTP durante 5 minutos. Después de ese punto, se aplicarán las reglas cache-control del recurso. Como resultado, cuando un usuario hace clic en un vínculo y se mueve a una ruta determinada, los fragmentos se recuperan de la caché, lo que mejora en gran medida el tiempo que se tarda en renderizar esa ruta.

Conclusión

La precarga puede mejorar mucho los tiempos de carga de las navegaciones futuras. En las apps de una sola página de React, esto se puede lograr cargando los fragmentos asociados con cada ruta, antes de que el usuario llegue a ellas. La solución de Quicklink para React SPA usa webpack-route-manifest para crear un mapa de rutas y fragmentos, con el fin de determinar qué archivos se deben recuperar previamente cuando aparece un vínculo en la vista. Implementar esta técnica en todo tu sitio puede mejorar en gran medida las navegaciones hasta el punto de hacer que parezcan instantáneas.