Улучшение производительности сборки css webpack (4)

Я перехожу с gulp на настройку webpack. Я хочу, чтобы webpack обрабатывал мои ресурсы js и css и упаковывал их в пакеты. Я установил 2 файла конфигурации webpack: один для js и один для css.

Общие размеры ресурсов css и js в моем проекте схожи: примерно 70 файлов (минимизировано 400 КБ) в каждом разделе.

Мой вопрос связан с низкой производительностью веб-пакета при обработке ресурсов css по сравнению с js.

Сравнивать:

  • Сборка JS (первый запуск): 15-30 секунд
  • Сборка JS (с кешем): 2 секунды

  • Сборка CSS (первый запуск): 15 секунд

  • Сборка CSS (с кешем): 10 секунд

    Очевидно, что конструктор CSS не так эффективно использует кеш, как часть CSS. Честно говоря, я не думаю, что он вообще использует кеширование (node_modules / .cache не имеет ничего общего), и единственная причина, по которой второй запуск выполняется быстрее, - это разогрев файловой системы.

    Проблема в режиме часов еще больше. Я провел тест, в котором я запускаю webpack в режиме просмотра и изменяю один небольшой файл (всего несколько строк), который должен быть включен в более крупный пакет:

  • Обновление JS: 150 мс

  • Обновление CSS: 1200-2000 мс

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

Более того, кажется, что увеличение количества точек входа также отрицательно влияет на время обновления. Больше записей = более медленное обновление, даже если обновление затрагивает только один крошечный файл.

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

Мое текущее предположение состоит в том, что загрузчик sass не использует кеширование и что при каждом обновлении модуля весь пакет должен компилироваться с нуля и снова и снова проходить через sass> postcss> css> extract pipe. Интересно, лучше ли будет делегировать управление импортом postcss-import и запускать sass после postcss. Я попытался написать совместимый с sass преобразователь импорта для postcss-import. Кажется, он работает немного быстрее в небольшой тестовой среде, но использование его в нашем реальном проекте приводит к сбою webpack :( Не было достаточно времени, чтобы выяснить, почему это происходит.

Как я могу улучшить время сборки CSS для моей текущей настройки?

Мои конфигурации JS и CSS ниже.

JS:

const path  = require('path');
const merge = require('webpack-merge');
const EntryPlugin = require('webpack-watched-glob-entries-plugin');
const dir = require('./node/dirconfig');

// use NODE_ENV var to switch between production and development
const devel = (process.env.NODE_ENV == 'development');

// base config for both prod and devel modes
let config = 
{
    name: 'scripts',

    // webpack preset
    // this should take care of production optimizations automatically
    mode: devel ? 'development' : 'production',

    // use all js files inside bundle dir as entries
    entry: EntryPlugin.getEntries(
        dir.assets + '/js/bundle/*.js'
    ),

    output: {
        path: dir.static + '/js',
        filename: "[name].js"
    },

    externals: {
        jquery: 'jQuery'
    },

    resolve: {
        modules: [dir.assets + '/js', 'node_modules']
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true,
                    },
                },
            },
        ]
    },

    plugins: [
        new EntryPlugin(),
    ],
};


// additional config for development mode
const development = 
{
    // add eslint loader
    module: {
        rules: [
            {
                enforce: "pre", // make sure this rule gets executed first
                test: /\.js$/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'eslint-loader',
                    options: {
                        cache: true,
                    },
                },
            },
        ]
    }
};

module.exports = merge(config, devel ? development : {});

CSS:

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const EntryPlugin = require('webpack-watched-glob-entries-plugin');
const dir = require('./node/dirconfig');

// use NODE_ENV var to switch between production and development
const devel = (process.env.NODE_ENV == 'development');

// base config for both prod and devel modes
let config = 
{
    name: 'styles',

    // webpack preset
    mode: devel ? 'development' : 'production',

    // use all .scss files which don't start with _ as entries
    entry: EntryPlugin.getEntries(
        dir.assets + '/sass/**/!(_*).scss'
    ),

    output: {
        path: dir.static + '/css',
        filename: "[name].js"
    },

    // enable sourcemaps in devel mode
    devtool: devel ? 'inline-source-map' : false,

    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    // 'cache-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: devel,
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            sourceMap: devel,
                        },
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: devel,
                        }
                    },
                ]
            },
        ]
    },

    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].css", // relative to path setting in the output section
        }),
        new EntryPlugin()
    ],
};

module.exports = config;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
561
1

Ответы 1

  1. Добавьте загрузчик потоков в загрузчики обработки js.
  2. Замените css-loader на fast-css-loader и sass-loader на fast-sass-loader.
  3. Поместите cache-loader в качестве первого загрузчика js файлов и после извлечения плагина в загрузчики css.

Другие вопросы по теме