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
decacheDirectory
-
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"
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')
o 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
Optimizado
Compilando por primera vez:
Segunda compilación:
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
Como puede ver, se necesitan 50
Optimizado
Primer comienzo
Segundo comienzo
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 chunk
mejorar 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、加载器和所有从你的配置中引用的模块都会被自动添加
},
},
};