В этой статье в основном записаны следующиеwebpack
Оптимизация производительности
статус-кво
По мере того, как проект продолжает расти и развиваться, количество компонентов начинает становиться все больше и больше, и проект начинает становиться большим,webpack
Время компиляции будет все больше и больше, наш текущий проект компилируется один раз в40s ——70s
Между тем, это очень неэффективная операция. Есть много способов оптимизации, в проекте уже сделано многое, в этой статье мы оптимизируем и объясним с точки зрения кэширования.
Далее представлены только несколько методов оптимизации, связанных с кешем, в том числе
-
babel-loader
изcacheDirectory
cache-loader
-
dll
динамически подключаемая библиотека HardSourceWebpackPlugin
Сначала о выводе: первый уже в проекте, второй и третий малоэффективны, а четвертый добился ожидаемого эффекта.
Наша версия веб-пакета: 4.41.2, система: mac os
Анализ узких мест
Первым шагом в оптимизации должен быть анализ текущей производительности, здесь мы используемspeed-measure-webpack-plugin
Делайте анализ скорости
// 安装
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()
]
});
Результаты аналогичны следующим, вы можете видеть, что каждыйLoader
так же какPlugin
отнимает много времени, с этим мы можем «прописать правильное лекарство»
Но следует отметить, что:HardSourceWebpackPlugin и speed-measure-webpack-plugin нельзя использовать вместе, меня это надолго угнетало
cacheDirectory из babel-loader
babel-loader
с разрешенияBabel
а такжеwebpack
переводитьJavaScript
файл, иногда, если мы запускаемbabel-loader
Медленно, вы можете рассмотреть возможность обеспечения того, чтобы документы были нанесены возможными. Вы можете использовать/\.m?js$/
совпадать, чтобы можно было перевестиnode_modules
каталог или другой нежелательный исходный код, вызывающий снижение производительности
в состоянии пройтиexclude
Исключите некоторые файлы, которые не нужно компилировать. Например, следующее не будет экранированоnode_modules
а такжеbower_components
Содержимое под папкой
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']
}
}
}
]
}
Вы также можете сделать это, используяcacheDirectory
вариант, будетbabel-loader
Ускорьтесь хотя бы в два раза. Это кэширует результат перевода в файловую систему.cacheDirectory
По умолчаниюfalse
. Если установлено, указанный каталог будет использоваться для кэшированияloader
результат исполнения. Послеwebpack
Сборка попытается прочитать кеш, чтобы избежать высокого потребления производительности, которое может происходить каждый раз при ее выполнении.Babel
Процесс перекомпиляции (recompilation process
). Если установлено нулевое значение(loader: 'babel-loader?cacheDirectory')
илиtrue (loader: 'babel-loader?cacheDirectory=true')
, загрузчик будет использовать каталог кеша по умолчаниюnode_modules/.cache/babel-loader
, если не найден ни в одном корневом каталогеnode_modules
каталог, он будет переведен обратно в каталог временных файлов операционной системы по умолчанию.
{
test: /\.js$/,
use: 'babel-loader?cacheDirectory',
include: [resolve('src'), resolve('test') ,resolve('node_modules/webpack-dev-server/client')]
}
cache-loader
Кромеbabel-loader
, если мы хотим другиеloader
Результаты обработки тоже кешируются, что делать?
Ответ заключается в том, что вы можете использоватьcache-loader
. В некоторых накладных расходахloader
добавлено доcache-loader
, чтобы кэшировать результаты на диск
Установить
npm install --save-dev cache-loader
настроить
module.exports = {
module: {
rules: [
{
test: /\.ext$/,
use: ['cache-loader', ...loaders],
include: path.resolve('src'),
},
],
},
};
⚠️ Обратите внимание, что сохранение и чтение этих файлов кеша потребует некоторого времени, поэтому используйте этот загрузчик только для загрузчиков с высокой производительностью.
В дополнение к конфигурации по умолчанию,cache-loader
Доступны еще несколько вариантов, см.cache-loader
схема кеширования dll
Что такое DLL?
Файл DLL — это библиотека с динамической компоновкой, а библиотека с динамической компоновкой может содержать функции и данные, которые вызываются другими модулями.
Зачем использовать DLL?
Причина в том, что динамическую библиотеку, содержащую большое количество повторно используемых модулей, нужно скомпилировать только один раз, и модули, включенные в динамическую библиотеку, не будут перекомпилироваться в последующем процессе построения, но код в динамической библиотеке будет использоваться напрямую. Поскольку большинство библиотек динамической компоновки содержат часто используемые сторонние модули, такие какVue react、react-dom
, пока версия этих модулей не обновлена, динамическую библиотеку не нужно перекомпилировать
как использовать?
Чтобы выполнить следующие три шага:
- отстраниться. Извлеките основные модули, от которых зависят веб-страницы, и упакуйте их в отдельные динамически подключаемые библиотеки. Динамическая библиотека может содержать несколько модулей.
- Получать. Когда импортируемый модуль существует в динамической библиотеке, этот модуль нельзя снова упаковать, но можно получить из динамической библиотеки.
- нагрузка. Все библиотеки динамических ссылок, от которых зависит страница, должны быть загружены.
использовался раньшеDllPlugin
а также DllReferencePlugin
Готово, но его конфигурация очень сложная и dll нужно перегенерировать вручную, если файлы обновляются. выбрано здесьAutoDllPlugin, он автоматически выполнит функции двух вышеуказанных плагинов, т.е.Vue-cli
плагин, который я использовал
Установить:
webpack 4
npm install --save-dev autodll-webpack-plugin
webpack 2 / 3
npm install --save-dev autodll-webpack-plugin@0.3
Основное использование:
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'
]
}
})
]
До оптимизации
Оптимизировано
Первая компиляция:
Вторая компиляция:
Оптимизировано на несколько секунд, с небольшим эффектом
Это не сработало так хорошо, потому чтоwebpack4
Спектакль достаточно отличный.Vue-cli
также убрал эту функцию
HardSourceWebpackPlugin
Установить:
npm install --save-dev hard-source-webpack-plugin
# or
yarn add --dev hard-source-webpack-plugin
Конфигурация:
// webpack.config.js
var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
context: // ...
entry: // ...
output: // ...
plugins: [
new HardSourceWebpackPlugin()
]
}
До оптимизации
Как видите, требуется 50 с.
Оптимизировано
первый старт
второй старт
Требуется всего 7 с, что снижает43 s
, скорость увеличивается примерно на 80%. Цель оптимизации достигнута!
Скорость горячего обновления
Видетьissue
Я упомянул о горячих обновлениях и сказал, что это будет медленнее. Я использовал наш проект для некоторых тестов. Ниже приведены тестовые данные.
До оптимизации
js: 2443ms 1634ms 1844ms 2532ms 1443ms 1248ms
html: 1094ms 1232ms 1119ms 1490ms 1264ms
css: 1422ms 1186ms 1341ms 1562ms 1183ms
Оптимизировано
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
Для сравнения, это иногда медленнее, но в целом приемлемо. Но это также имело некоторое влияние, поэтому проект поднял дваnpm script
команду, если вы не хотите ее открывать, вы можете напрямую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"
}
существуетbuild/webpack.dev.conf.js
середина
if (args.cache) {
devConfig = merge(devConfig, {
plugins: [new HardSourceWebpackPlugin()]
})
}
еще раз подчеркнуть:
HardSourceWebpackPlugin и speed-measure-webpack-plugin нельзя использовать вместе
Глядя в будущее
webpack 5
Вышел, с привлекательной фичей - постоянным кэшированием (говорят, что идея связана сHardSourceWebpackPlugin
согласуется)
пройти черезcache
Кэшwebpack
модули и chunk
, чтобы улучшить скорость сборки.cache
будет установлен в режиме разработки наtype: 'memory'
и отключен в производственном режиме
module.exports = {
cache: {
// 1. 将缓存类型设置为文件系统
type: 'filesystem',
buildDependencies: {
// 2. 将你的 config 添加为 buildDependency,以便在改变 config 时获得缓存无效
config: [__filename],
// 3. 如果你有其他的东西被构建依赖,你可以在这里添加它们
// 注意,webpack、加载器和所有从你的配置中引用的模块都会被自动添加
},
},
};
Суммировать
Вышеупомянутое исследование заняло у автора много времени, блюдо - первородный грех, и его еще нужно накопить. Другое ощущение, что интерфейс развивается так быстро, что многие вещи могут быть устаревшими, и только поддержание непрерывного обучения и прочных базовых знаний имеет решающее значение.
Выше, я надеюсь помочь вам