Optimización del rendimiento del paquete web: mejora la velocidad de compilación del paquete web

Este artículo registra principalmente la siguiente  webpack optimización del rendimiento.

status quo

A medida que el proyecto continúa desarrollándose y creciendo, el número de componentes comienza a aumentar, el proyecto también comienza a crecer y el webpack tiempo de compilación será cada vez más largo Nuestro proyecto actual se compila una sola vez  40s ——70s , lo cual es muy ineficiente. Hay muchos métodos de optimización. El proyecto anterior ya ha hecho mucho. Este artículo explicará la optimización desde la perspectiva del almacenamiento en caché.

A continuación, solo se presentan varios métodos de optimización relacionados con el almacenamiento en caché, incluidos

  • babel-loader de cacheDirectory

  • cache-loader

  • dll Biblioteca de enlaces dinámicos

  • HardSourceWebpackPlugin

Permítanme hablar primero de la conclusión, la primera es la existente en el proyecto, la segunda y la tercera tienen poco efecto, y la cuarta ha logrado el efecto esperado.

Versión de nuestro paquete web: 4.41.2, sistema: mac os

Análisis de cuellos de botella

El primer paso de la optimización debe ser analizar el rendimiento actual, aquí usamos el  speed-measure-webpack-plugin análisis de velocidad

// 安装
npm install --save-dev speed-measure-webpack-plugin
// 使用方式
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
 
const smp = new SpeedMeasurePlugin();
 
const webpackConfig = smp.wrap({
  plugins: [
    new MyPlugin(),
    new MyOtherPlugin()
  ]
});

Los resultados son similares a los siguientes, puedes ver  el tiempo que llevan todos Loader y  cada uno  Plugin, con esto, podemos "prescribir el medicamento adecuado"

imagen

Pero debe tenerse en cuenta que: HardSourceWebpackPlugin y speed-measure-webpack-plugin no se pueden usar juntos , lo que me deprime durante mucho tiempo.

babel-loader 的 cacheDirectory

babel-loader Está permitido usar  Babel y  webpack traducir  JavaScript archivos. A veces, si corremos  babel-loader muy lentamente, podemos considerar asegurarnos de que se traduzcan la menor cantidad posible de archivos. Puede usar  /\.m?js$/ para hacer coincidir, que puede traducir  node_modules directorios u otros códigos fuente innecesarios, lo que da como resultado una degradación del rendimiento.

Puede  exclude excluir algunos archivos que no necesitan compilarse. Por ejemplo, lo siguiente no se escapará  node_modules y  bower_components el contenido de la carpeta

module: {
  rules: [
    {
      test: /\.m?js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env'],
          plugins: ['@babel/plugin-proposal-object-rest-spread']
        }
      }
    }
  ]
}

También puede  acelerar al menos dos veces mediante el uso de  cacheDirectory opciones  babel-loader. Esto almacenará en caché el resultado de la traducción en el sistema de archivos. cacheDirectory El valor predeterminado es  false. Cuando se establece, el directorio especificado se utilizará para almacenar en caché  loader los resultados de la ejecución. En webpack construcciones posteriores  , intentará leer la caché para evitar el Babel proceso de recompilación de consumo de alto rendimiento que puede ocurrir cada vez que se ejecuta  ( recompilation process). Si se establece un valor vacío  (loader: 'babel-loader?cacheDirectory')true (loader: 'babel-loader?cacheDirectory=true'), el cargador utilizará el directorio de caché predeterminado node_modules/.cache/babel-loader. Si no se encuentra ningún node_modules directorio en ningún directorio raíz  , se degradará y volverá al directorio de archivos temporales predeterminado del sistema operativo.

{
  test: /\.js$/,
  use: 'babel-loader?cacheDirectory',
  include: [resolve('src'), resolve('test') ,resolve('node_modules/webpack-dev-server/client')]
}

cargador de caché

Excepto  babel-loader, si queremos loader almacenar en caché otros  resultados de procesamiento, ¿qué debemos hacer?

La respuesta es que se puede utilizar  cache-loader. loader Agregue antes  algunos gastos generales de alto rendimiento  cache-loader, para almacenar en caché los resultados en el disco

instalación

npm install --save-dev cache-loader

Configuración

module.exports = {
  module: {
    rules: [
      {
        test: /\.ext$/,
        use: ['cache-loader', ...loaders],
        include: path.resolve('src'),
      },
    ],
  },
};

⚠️ Tenga en cuenta que guardar y leer estos archivos de caché tendrá algún tiempo de sobrecarga, así que utilice este cargador solo para el cargador con sobrecarga de alto rendimiento

Además de la configuración predeterminada, cache-loader se proporcionan algunas otras opciones, consulte el cargador de caché [1] para obtener más detalles.

esquema de almacenamiento en caché dll

¿Qué es una DLL?

El archivo DLL es una biblioteca de vínculos dinámicos y una biblioteca de vínculos dinámicos puede contener funciones y datos llamados para otros módulos.

¿Por qué utilizar DLL?

La razón es que la biblioteca de enlaces dinámicos que contiene una gran cantidad de módulos reutilizados solo necesita compilarse una vez, y los módulos contenidos en la biblioteca de enlaces dinámicos no se volverán a compilar en el proceso de construcción posterior, sino que utilizarán directamente el código en el enlace dinámico. Biblioteca. Dado que la mayor parte de la biblioteca de vínculos dinámicos contiene módulos de terceros de uso común, por ejemplo  Vue react、react-dom, siempre que no se actualice la versión de estos módulos, no es necesario volver a compilar la biblioteca de vínculos dinámicos.

¿cómo utilizar?

Para completar los siguientes tres pasos:

  • Arrancar. Extraiga los módulos básicos de los que depende la página web y empaquételos en bibliotecas de vínculos dinámicos independientes. Una biblioteca de enlaces dinámicos puede contener varios módulos

  • Obtener. Cuando el módulo que debe importarse existe en una biblioteca de vínculos dinámicos, este módulo no se puede empaquetar nuevamente, sino que se obtiene de la biblioteca de vínculos dinámicos.

  • carga. Todas las bibliotecas de enlaces dinámicos de las que depende la página deben cargarse

Usado DllPlugin y  DllReferencePlugin completado antes  , pero su configuración es muy complicada, y si el archivo se actualiza, la dll debe regenerarse manualmente. AutoDllPlugin [2] está seleccionado aquí, completará automáticamente las funciones de los dos complementos anteriores, este es Vue-cli un complemento que  se ha utilizado

instalación:

paquete web 4

npm install --save-dev autodll-webpack-plugin

paquete web 2/3

npm install --save-dev [email protected]

Uso básico:

plugins: [
  new HtmlWebpackPlugin({
    inject: true,
    template: './src/index.html',
  }),
  new AutoDllPlugin({
    inject: true, // will inject the DLL bundles to index.html
    filename: '[name].js',
    entry: {
      vendor: [
        'react',
        'react-dom'
      ]
    }
  })
]

Antes de la optimización

imagen

Optimizado

Compilando por primera vez:

imagen

Segunda compilación:imagen

Optimizado durante unos segundos, pero poco efecto.

El resultado no es muy efectivo, porque  webpack4 el rendimiento es lo suficientemente bueno Vue-cli y esta función también está abolida.

HardSourceWebpackPlugin

instalación:

npm install --save-dev hard-source-webpack-plugin
# or
yarn add --dev hard-source-webpack-plugin

Configuración:

// webpack.config.js
var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');

module.exports = {
  context: // ...
  entry: // ...
  output: // ...
  plugins: [
    new HardSourceWebpackPlugin()
  ]
}

Antes de la optimización

imagen

Como puede ver, se necesitan 50

Optimizado

Primer comienzo

imagen

Segundo comienzo

imagen

Solo toma 7 s, que se reduce  43 s, y la velocidad aumenta en aproximadamente un 80%. ¡Se logra el propósito de la optimización!

Velocidad de actualización en caliente

Al ver  issue que mencionó sobre actualización en caliente, será más lento, usé nuestro proyecto para hacer algunas pruebas, los siguientes son los datos de prueba

Antes de la optimización

js: 2443ms 1634ms 1844ms 2532ms 1443ms 1248ms

html: 1094ms 1232ms 1119ms 1490ms 1264ms

css: 1422ms 1186ms 1341ms 1562ms 1183ms

Optimizado

js: 2429ms 2436ms 2860ms 2528ms 1917ms 1487ms 1450ms 1450ms 1557ms 2198ms

html: 2855ms 1569ms 1400ms 1298ms 1204ms 1299ms 1578ms 1485ms 2028ms

css: 2035ms 1406ms 1415ms 1600ms 1773ms 1604ms

En comparación, a veces es un poco más lento, pero en general es aceptable. Pero también hay algunos impactos, por lo que se agregaron dos npm script comandos al proyecto  . Si no desea abrirlo, puede hacerlo directamente npm run dev:noCache

"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --cache=true",
  "dev:noCache": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --cache=false"
}

En  build/webpack.dev.conf.js el

if (args.cache) {
  devConfig = merge(devConfig, {
    plugins: [new HardSourceWebpackPlugin()]
  })
}

enfatizar de nuevo:

HardSourceWebpackPlugin y speed-meter-webpack-plugin no se pueden usar juntos

Mira al futuro

webpack 5 Se ha lanzado, que tiene un caché persistente de características muy atractivo (se dice que el pensamiento  HardSourceWebpackPlugin es el mismo)

Al  cache  almacenar en caché los webpack módulos generados  y chunkmejorar la velocidad de construcción. cache Se configurará en modo de desarrollo  type: 'memory' y se desactivará en modo de producción.

module.exports = {
  cache: {
    // 1. 将缓存类型设置为文件系统
    type: 'filesystem',

    buildDependencies: {
      // 2. 将你的 config 添加为 buildDependency,以便在改变 config 时获得缓存无效
      config: [__filename],

      // 3. 如果你有其他的东西被构建依赖,你可以在这里添加它们
      // 注意,webpack、加载器和所有从你的配置中引用的模块都会被自动添加
    },
  },
};

Supongo que te gusta

Origin blog.csdn.net/AN0692/article/details/114358197
Recomendado
Clasificación