Passer au contenu principal




Un nouveau stratégie de fragmentación de paquetes la toile en Next.js y Gatsby minimiza el código duplicado para impulsar el rendimiento de carga de la página.

Chrome está colaborando con herramientas y marcos en el ecosistema de Open source de JavaScript. Recientemente se agregaron varias optimizaciones más nuevas para impulsar el rendimiento de carga de Next.js y
Gatsby. Este Publier cubre una estrategia de fragmentación granular mejorada que ahora se envía de forma predeterminada en ambos marcos.

Présentation

Como muchos frameworks web, Next.js y Gatsby utilizan package web como su agrupador principal. webpack v3 ingresado
CommonsChunkPlugin para hacer factible la salida de módulos compartidos entre diferentes puntos de entrada en un solo (o pocos) fragmentos (o fragmentos) «comunes». El código compartido se puede descargar de forma separada y almacenar en la cache du le navigateur desde el principio, lo que puede resultar en un mejor rendimiento de carga.

Ce modèle est devenu populaire avec de nombreux frameworks d'applications à page unique qui ont adopté un point d'entrée et une configuration de paquet qui ressemblaient à ceci:

diagramme-modèle-commun-7854309

Aún cuando es práctico, el concepto de agrupar todo el código del módulo compartido en un solo fragmento tiene sus limitaciones. Los módulos no compartidos en cada punto de entrada se pueden descargar para rutas que no lo usan, lo que resulta en la descarga de más código del necesario. A modo de ejemplo, cuando Page 1 charger le commun extrait de code, chargez le code de moduleC aún cuando Page 1 no utiliza moduleC. Pour cette raison, avec quelques autres, webpack v4 a supprimé le plugin au profit d'un nouveau: SplitChunksPlugin.

Fragmentation améliorée

Les paramètres par défaut pour SplitChunksPlugin anda bastante bien para la mayoría de los usuarios. Se crean varios fragmentos divididos en función de una serie de termes
para evitar la consecución de código duplicado en varias rutas.

A pesar de todo, muchos frameworks web que utilizan este complemento siguen un enfoque de «común único» para la división de fragmentos. Next.js, a modo de ejemplo, generaría un Chambre des communes paquete que contenía cualquier módulo que se usa en más del 50% de las páginas y todas las dependencias del marco (réagir, réagir-dom, et donc).

const splitChunksConfigs = {

prod: {
chunks: 'all',
cacheGroups: {
défaut: faux,
vendors: faux,
Chambre des communes: {
patate douce: 'commons',
chunks: 'all',
minChunks: totalPages > 2 ? totalPages * 0.5 : 2,
},
réagir: use-subscription)[/]/,
,
},
},

Aún cuando incluir código dependiente del marco en un fragmento compartido significa que se puede descargar y almacenar en caché para cualquier punto de entrada, la heurística basada en el uso de incluir módulos comunes utilizados en más de
la moitié des pages no es muy eficaz. La modificación de esta proporción solo daría como consecuencia uno de dos resultados:

  • Si vous réduisez le ratio, plus de code inutile est téléchargé.
  • L'augmentation du ratio dupliquera plus de code sur plusieurs chemins.

Para solucionar este problema, Next.js adoptó un configuración distinto afin deSplitChunksPlugin ce qui réduit le code inutile pour n'importe quel itinéraire.

  • Tout module tiers suffisamment volumineux (plus de 160 Ko) se divise en son propre bloc individuel
  • Une séparation cadres un extrait de code est créé pour les dépendances du framework (réagir, réagir-dom, et donc)
  • Autant de fragments partagés sont créés que nécessaire (jusqu'à 25)
  • La taille minimale pour générer un fragment est passée à 20 Ko

Cette stratégie de fragmentation granulaire offre les avantages suivants:

  • Les temps de chargement des pages sont améliorés. La diffusion de plusieurs extraits partagés, plutôt qu'un seul, minimise la quantité de code inutile (ou dupliqué) pour tout point d'entrée.
  • Amélioration de la mise en cache lors de la navigation. La división de bibliotecas grandes y dependencias del marco en fragmentos separados reduce la oportunidad de invalidación de caché, puesto que es poco probable que ambos cambien hasta que se realice una actualización.

Vous pouvez voir la configuration complète adoptée par Next.js sur webpack-config.ts.

Más solicitudes HTTP

SplitChunksPlugin definió la base para la fragmentación granular, y aplicar este enfoque a un marco como Next.js no era un concepto totalmente nuevo. A pesar de todo, muchos frameworks continuaron utilizando una única estrategia heurística y de paquetes «comunes» por algunas razones. Esto incluye la preocupación de que muchas más solicitudes HTTP puedan afectar negativamente al rendimiento del sitio.

Les navigateurs solo pueden abrir un número limitado de conexiones TCP a un solo origen (6 para Chrome), por lo que minimizar el número de fragmentos generados por un agrupador puede asegurar que el número total de solicitudes permanezca por debajo de este umbral. A pesar de todo, esto solo es cierto para HTTP / 1.1. La multiplexación en HTTP / 2 posibilita transmitir diversos solicitudes en paralelo utilizando una sola conexión sobre un solo origen. Dicho de otra forma, de forma general no tenemos que preocuparnos por limitar la cantidad de fragmentos emitidos por nuestro agrupador.

Tous les principaux navigateurs admite HTTP / 2. Los equipos de Chrome y Next.js querían ver si incrementar el número de solicitudes dividiendo el paquete «commons» único de Next.js en varios fragmentos compartidos afectaría el rendimiento de carga de alguna manera. Comenzaron midiendo el rendimiento de un solo sitio mientras modificaban el número máximo de solicitudes paralelas usando el
maxInitialRequests

propriété.

performances-num-requests-1-2748678

En un promedio de tres ejecuciones de diversos pruebas en una sola página web, el
charge,
start-render
y los tiempos de First Contentful Paint permanecieron prácticamente iguales al variar el número máximo de solicitudes iniciales (de 5 a 15). Curiosamente, notamos una ligera sobrecarga de rendimiento solo posteriormente de dividir de forma agresiva a miles de solicitudes.

performances-num-requests-2-1561814

Esto mostró que mantenerse por debajo de un umbral confiable (20 ~ 25 solicitudes) logró el equilibrio adecuado entre el rendimiento de carga y la eficiencia del almacenamiento en caché. Posteriormente de algunas pruebas de referencia, se seleccionó 25 como maxInitialRequest raconter.

La modification du nombre maximal de demandes qui se produisent en parallèle a abouti à plusieurs packages partagés et leur séparation appropriée pour chaque point d'entrée a considérablement réduit la quantité de code inutile pour la même page.

js-payload-num-requests-7283783

Cette expérience consistait uniquement à modifier le nombre de requêtes pour voir s'il y aurait un effet négatif sur les performances de chargement de la page. Les résultats suggèrent que la configuration maxInitialRequests à
25 en la página de prueba fue óptimo debido a que redujo el tamaño de la carga útil de JavaScript sin ralentizar la página. La cantidad total de JavaScript que se necesitaba para hidratar la página seguía siendo la misma, lo que explica por qué el rendimiento de carga de la página no necesariamente mejoró con la cantidad reducida de código.

webpack utiliza 30 KB como tamaño mínimo predeterminado para que se genere un fragmento. A pesar de todo, acoplar un
maxInitialRequests une valeur de 25 avec une taille minimale de 20 Ko a permis une meilleure mise en cache.

Réductions de taille avec des morceaux granulaires

Muchos marcos, incluido Next.js, se centran en el enrutamiento del lado del client (manejado por JavaScript) para inyectar etiquetas de script más nuevas para cada transición de ruta. Pero, ¿cómo predeterminan estos fragmentos dinámicos en el momento de la construcción?

Next.js utiliza un archivo de manifiesto de compilación del lado del serveur para establecer qué fragmentos generados son utilizados por diferentes puntos de entrada. Para proporcionar esta información además al cliente, se creó un archivo de manifiesto de compilación abreviado del lado del cliente para adjudicar todas las dependencias para cada punto de entrada.


getDependencies (route) {
revenir Este.promisedBuildManifest.then(
man => (man[route] && man[route].map(dirección url => `/_next/${dirección URL}`)) || []
)
}

morceaux-de-sortie-9444947

Cette nouvelle stratégie de fragmentation granulaire a d'abord été implémentée dans Next.js derrière un indicateur, où elle a été testée sur plusieurs premiers utilisateurs. Beaucoup ont constaté une réduction significative du JavaScript total utilisé pour l'ensemble de leur site:

La version finale a été livrée par défaut en version 9.2.

Gatsby

Gatsby utilizado para seguir el mismo enfoque de usar una heurística basada en el uso para establecer módulos comunes:

config.optimization = {

splitChunks: {
patate douce: faux,
chunks: ``,
cacheGroups: {
défaut: faux,
vendors: faux,
Chambre des communes: {
patate douce: `Chambre des communes`,
chunks: ``,


minChunks: componentsCount > 2 ? componentsCount * 0.5 : 2,
},
réagir: réagir-dom,

Al aprovechar al máximo la configuración de su paquete web para adoptar una estrategia de fragmentación granular semejante, además notaron reducciones considerables de JavaScript en muchos sitios grandes:

Jetez un œil à PR para saber cómo implementaron esta lógica en la configuración de su paquete web, que se envía de forma predeterminada en v2.20.7.

conclusion

El concepto de envío de fragmentos granulares no es específico de Next.js, Gatsby o inclusive webpack. Todo el mundo debería considerar mejorar la estrategia de fragmentación de su aplicación si sigue un gran enfoque de paquete «común», independientemente del marco o paquete de módulos utilizado.

  • Si vous souhaitez voir les mêmes optimisations de segmentation appliquées à une application React vanilla, jetez un œil à ceci Exemple d'application React. Usa una versión simplificada de la estrategia de fragmentación granular y puede ayudarlo a empezar a aplicar el mismo tipo de lógica a su sitio.
  • Pour le cumul, les blocs sont créés de manière granulaire par défaut. Jette un coup d'œil à
    Chunks manuels si vous souhaitez configurer manuellement le comportement.