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 de Quicklink en una demostración de SPA de React para demostrar cómo la carga previa acelera las navegaciones posteriores.

Medir

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

  • 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 pantalla completa.

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

En la pestaña nueva que se acaba de abrir, completa las siguientes instrucciones:

  1. Presiona "Control + Mayús + J" (o bien "Comando + Opción + 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 de Regulació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 Filtrar para ocultar los recursos que no incluyan chunk en su nombre.

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

El sitio utiliza la división del código basada en rutas, por lo que 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.

Se cargan los fragmentos de JS y CSS de la nueva ruta para representar la página.

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

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

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

  • La división de código basada en rutas le indica al navegador que solo cargue los fragmentos necesarios con mayor prioridad en el tiempo de carga de la página.
  • La carga previa le indica al navegador que cargue los fragmentos de los vínculos en el 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 que asocia rutas con sus bloques correspondientes.

Por lo general, tendrás que instalar la biblioteca, pero ya lo hicimos por ti. Este es el comando que deberías 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 del paquete web, 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, agrega el siguiente código a la parte inferior de config-overrides.js para configurar el complemento webpack-route-manifest:

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 las 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 el archivo rmanifest.json se pueda generar 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, deberás instalar la biblioteca Quicklink en tu proyecto. Para simplificar, ya lo agregamos al proyecto. Este es el comando que deberías ejecutar:

npm install --save quicklink

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

Primero, importa el componente de orden 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 para 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 deben cargar previamente los fragmentos para las rutas unidas con withQuicklink() cuando el vínculo entra en la vista.

Volver a medir

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

Cuando la página de inicio carga los fragmentos de esa ruta. Después, Quicklink carga previamente los fragmentos de la ruta para los vínculos en el viewport:

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

Estos 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 de red 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 “caché con carga previa”, en lugar de la red. La carga de estos fragmentos sin un Quicklink tomó alrededor de 580 ms. Cuando usas la biblioteca, ahora tarda 2 ms, lo que representa una reducción del 99% .