Оптимизируйте скорость компиляции проектов webpack4 с помощью экспериментальных идей

Node.js внешний интерфейс JavaScript Webpack
Оптимизируйте скорость компиляции проектов webpack4 с помощью экспериментальных идей

Недавно при разработке я столкнулся с проблемой: когда проект становится все больше и больше, скорость сборки и компиляции webpack становится очень медленной. Хотя webpack4 официально заявляет, что скорость увеличилась более чем на 90%, в реальном использовании он похож на webpack2. Я действительно не могу ждать несколько секунд для компиляции при горячей перезагрузке, поэтому я начал путь оптимизации.
Конечный эффект оптимизации хороший, ускорение достигло более 80%. Попутно я оптимизировал в соответствии с мыслями о проведении экспериментов ранее и сталкивался с различными проблемами.Вместо того, чтобы делиться методом решения проблемы, я хотел бы поделиться идеей решения проблемы.

Сначала определите цели

Прежде чем проводить эксперимент, мы должны сначала поставить цель.
Но вот проблема.Хотя это кажется очень медленным, я не знаю, сколько времени это заняло и где медлительность, поэтому нет никакого способа узнать, насколько мы можем оптимизировать, и нет никакого способа начать оптимизацию. . Итак, первая задача — получить информацию о процессе компиляции веб-пакета.
Порывшись в официальной документации webpack, я обнаружил, что свойство devServer.stats в конфигурации может получить полную информацию о процессе компиляции

stats: {
    timings: true,
    modules: false,
    assets: false,
    entrypoints: false,
    assetsSort: 'field',
    builtAt: false,
    cached: false,
    cachedAssets: false,
    children: false,
    chunks: false,
    chunkGroups: false,
    chunkModules: false,
    chunkOrigins: false,
    performance: true,
    errors: true,
    warnings: true,
},

После такой настройки мы получаем время сборки и компиляции:

Видно, что время сборки 40с, а время компиляции после изменения кода 5,4с.
Поскольку webpack4 утверждает, что может ускориться на 90%, в текущей ситуации должна быть некоторая неправильная конфигурация.Сначала мы поставим цель оптимизировать время компиляции до менее 1 с.

Угадайте, что может повлиять на скорость

Текущий проект представляет собой проект с несколькими записями, между каждой записью не так много связей, но они упакованы и скомпилированы вместе. Когда мы обычно разрабатываем, будет ли это быстрее, если мы будем компилировать только один входной файл за раз?
Изначально было три записи, но вы можете увидеть, когда загружается только одна запись:

Время сборки и компиляции ускоряется. Стало 30с и 3.4с.
Поскольку это эффективно, напишите несколько команд для облегчения разработки различных записей:

"scripts": {
    "dev": "webpack-dev-server  --config ./webpack.config/dev.js --hot --inline",
    "teacher": "app=teacher webpack-dev-server  --config ./webpack.config/dev.js --hot --inline",
    "student": "app=student webpack-dev-server  --config ./webpack.config/dev.js --hot --inline",
    "home": "app=home webpack-dev-server  --config ./webpack.config/dev.js --hot --inline",
    }

Перед командой package.json dev с параметром app = XXX

const teacherEntry = {
    ueditor: [
        'babel-polyfill',
        './src/common/UEditor/ueditor.config.js',
        './src/common/UEditor/ueditor.all.js',
        './src/common/UEditor/kityformula-plugin/addKityFormulaDialog.js',
        './src/common/UEditor/kityformula-plugin/getKfContent.js',
        './src/common/UEditor/kityformula-plugin/defaultFilterFix.js'
    ],
    teacher: ['./src/app/teacher/index.js'],
    teacherLogin: './src/app/teacherLogin/js/teacherLogin.js'
};
const studentEntry = {
    student: ['babel-polyfill', './src/app/student/index.js'],
    studentLogin: './src/app/studentLogin/js/studentLogin.js'
};
const homeEntry = {
    home: './src/app/home/index.js'
};
const entryObj = {
    teacher: teacherEntry,
    student: studentEntry,
    home: homeEntry
};

const entry = process.env.app
    ? entryObj[process.env.app]
    : Object.assign({}, teacherEntry, studentEntry, homeEntry);

Затем добавьте код для загрузки разных записей в соответствии со значением process.env.app в webpack.base.config.js, чтобы реализовать эффект запуска разных команд для загрузки разных записей во время разработки.

Проверьте конфигурацию веб-пакета на предмет конфигурации, влияющей на производительность.

Затем используйте метод управления переменными, чтобы удалить загрузчик и плагин веб-пакета один за другим, а затем наблюдайте за сокращением времени.

new WriteFilePlugin({
    test: /^((?!hot-update).)*$/
}),

Я обнаружил, что использовался плагин для записи файлов, и все файлы были записаны в экспорт, но на самом деле писать нужно только файл html, поэтому я изменил его на

new WriteFilePlugin({
    test: /\.html$/,
    useHashIndex: true
}),

После изменения время сборки и компиляции стало 30 с и 3 с с небольшой оптимизацией.
Затем я обнаружил, что babel не игнорирует каталог node_modules при компиляции js.

{
    test: /\.js$/,
    include: /(src|node_modules\/flv.js)/,
    exclude: /(node_modules)/,
    loader: 'babel-loader'
},

После добавления обнаружил, что время стало 27с и 2,2с, что уже половина начала.

Контраст, чтобы увидеть проекты других людей, не имеют места для изучения

Конфигурация почти такая же, и проблем больше не обнаружено, поэтому я начал гуглить, чтобы найти чужие методы оптимизации.
Я нашел похожий проект позжеhappypack(многопоточная компиляция) иcache-loader(кэш), я чувствую, что эффект оптимизации неплох:

new HappyPack({
    id: 'babel', // 对于loaders id
    loaders: ['cache-loader', 'babel-loader?cacheDirectory'], // 是用babel-loader解析
    threadPool: happyThreadPool,
    verboseWhenProfiling: true // 显示信息
}),

После добавления happypack и cache-loader вы можете увидеть, что скорость первой сборки значительно увеличилась, снизившись до 13,5 с!
Но скорость компиляции практически не изменилась, по-прежнему 2 с. Революция еще не удалась, товарищи еще должны потрудиться.

Изучите информацию о процессе компиляции, чтобы найти точки оптимизации.

Чтобы еще больше оптимизировать скорость компиляции, мы должны проанализировать, что произошло в процессе компиляции.
Установите для активов в статистике значение true и наблюдайте за скомпилированными файлами:

Обнаружено, что каждый файл js имеет файл .map того же размера, не займет ли это вдвое больше времени! ? Так что быстро Google, чтобы узнать, где находится файл .map. Позже выяснилось, что он пришел из devtool в конфигурации webpack, которая в основном используется для отладки программ.Официальная инструкция по настройке выглядит следующим образом:

Выяснилось, что в проекте использована самая медленная source-map, поэтому я быстро модифицировал конфигурацию:

devtool: 'cheap-module-eval-source-map'

После изменения я попробовал его, и время сборки и компиляции сократилось до 11 с и 0,8 с.

Наконец, скорость компиляции была снижена до 1 с, и первоначальная цель была достигнута.

Суммировать

После этой оптимизации я чувствую, что конфигурация веб-пакета обширна и глубока. В каждом проекте могут быть разные проблемы, влияющие на скорость webpack, поэтому я разделяю идею локализации проблемы здесь, надеясь помочь друзьям, которые сталкиваются с похожими проблемами, найти проблему шаг за шагом и улучшить скорость.

Author: Brady