оптимизация упаковки веб-пакета

внешний интерфейс JavaScript Webpack Babel

Объемные статьи

1. Исходное состояние

2. Роутер загружается по запросу

Наконец, измените router.js и измените все маршруты на динамическую загрузку.

//router.js

//原来的写法:import Home from '@/components/PC/Home'
//改成下面这种形式(其他路由同理)
const Home = () => import('@/components/PC/Home') 

3. Добавляем dll

Добавьте файл webpack.dll.conf.js Dll существует независимо после упаковки.Пока содержащиеся в ней библиотеки не будут увеличены, уменьшены или обновлены, хэш не изменится.Поэтому код онлайн dll не нужно часто обновлять с выходом версии.

После изменения кода части приложения необходимо скомпилировать только код части приложения, а часть dll, пока включенные библиотеки не будут увеличены, уменьшены или обновлены, не нужно переупаковывать. Это также значительно повышает скорость каждой компиляции.

Предположим, у вас есть несколько проектов, которые используют одни и те же зависимые библиотеки, они могут совместно использовать dll

const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    mode: 'none',
    entry: {
        vue: ['vue/dist/vue.js', 'vue', 'vue-router', 'vuex'],
        comment: ['jquery', 'lodash', 'jquery/dist/jquery.js']
    },
    output: {
        path: path.join(__dirname, '../static/dll/'),
        filename: '[name].dll.js',
        library: '[name]'
    },
    plugins: [
        new webpack.DllPlugin({
            path: path.join(__dirname, '../static/dll/', '[name]-manifest.json'),
            name: '[name]'
        })
    ],
    optimization: {
        minimizer: [
            new UglifyJsPlugin()
        ]
    }
};

Выполните команду для создания dll jsonwebpack --config config/webpack.dll.conf.js

добавить плагины util.js

  new webpack.DllReferencePlugin({
            manifest: require('../static/dll/vue-manifest.json')
        }),

        new webpack.DllReferencePlugin({
            manifest: require('../static/dll/comment-manifest.json')
        })

index.html добавить ссылку на файл

        <script src="/static/dll/vue.dll.js"></script>
        <script src="/static/dll/comment.dll.js"></script>

4. Добавьте splitchunksplugin.

Извлечение модуля инициализации node_modules и установка кеша

 optimization: {
        splitChunks: {
            chunks: 'all',
            minChunks: 3,
            cacheGroups: {
                vendor: {
                    test: /node_modules/,
                    chunks: 'initial',
                    name: 'vendor',
                    priority: 10,
                    enforce: true
                }
            }
        }
    },

5. Извлечь css

 {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader'
            ]
        }

 new MiniCssExtractPlugin({
            filename: isBuild? 'css/[name].css':'css/[name]_[hash].css'
        })

5. Извлечь элемент пользовательского интерфейса

 element: {
                    test: /node_modules\/element-ui/,
                    chunks: 'initial',
                    name: 'element',
                    priority: 10,
                    enforce: true
                },

 new HtmlWebpackPlugin({
            template: './pages/index.html',
            chunks: ['vendor', 'app', 'element']
        })

6. Загружайте babel-polyfill по запросу

Недостатки babel-polyfill После использования запакованный объем получается очень большим, потому что babel-polyfill представляет собой единое целое, добавляющее все методы в цепочку прототипов. Например, мы используем только Array.from, но он также добавляет Object.defineProperty, что является пустой тратой времени. Использование @babel/runtime и @babel/plugin-transform-runtime После использования плагина Babel воспользуется инструментальными функциями из babel@runtime, чтобы переписать Promise в _Promise (только для примера), а затем представит вспомогательную функцию _Promise. Это позволяет избежать повторной упаковки кода и ручного импорта модулей.

.babel

 "plugins": [
      "@babel/plugin-transform-runtime"
    ]

polyfills.js удалить babel-polyfill

//import 'babel-polyfill';
//import "core-js/modules/es6.promise";

Суммировать

app.js 1.78M -> размер 125k уменьшен на 90%

размер vendor.js 324k -> 208k уменьшен на 35%

Он разделен и упакован в несколько пакетов из предыдущих 3 пакетов и загружается по запросу.

Скоростные статьи

building modules chunk asset optimization

Раньше было 60с-70с, а после оптимизации громкости стабилизировалось на 40-50с (стабильно на отметке 45с), а скорость нарастания была около 20%

1. Используйте плагин webpack-parallel-uglify-plugin для сжатия кода

Когда в Webpack есть несколько файлов JavaScript, которые необходимо вывести и сжать, UglifyJS будет использоваться для сжатия и вывода один за другим, но ParallelUglifyPlugin откроет несколько подпроцессов и распределит работу по сжатию нескольких файлов между несколькими подпроцессами для завершения.

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');

 new ParallelUglifyPlugin({
                uglifyOptions: {
                    // 最紧凑的输出
                    beautify: false,
                    // 删除所有的注释
                    comments: false,
                    compress: {
                        warnings: false, // 警告开关
                        drop_console: true,
                        // 内嵌定义了但是只用到一次的变量
                        collapse_vars: true,
                        // 提取出出现多次但是没有定义成变量去引用的静态值
                        reduce_vars: true
                    }
                },
                sourceMap: false,
                parallel: true , // 并行处理打包文件
                cache: true // 使用缓存

            })

[34,463, 38,368, 37,928, 36,127, 38,007] Среднее значение 36,9786 36 секунд укорочены и стабилизированы на уровне 30-40 секунд после добавления около 10 секунд

2. Используйте Happypack для ускорения сборки кода

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

 new HappyPack({
            id: 'babel',
            loaders: [
                {
                    loader: 'babel-loader',
                    query: '?cacheDirectory',
                    options: {
                        presets: ['@babel/env']
                    }
                }],
            threadPool: happyThreadPool,
            verbose: true
        }),

 {
            test: /\.js$/,
            include: [srcPath, iqiyiPath],
            exclude: /(node_modules|bower_components)/,
            loader: 'happypack/loader?id=babel'
        },

[35,357, 37,762, 44,798, 33,635, 33,427, 33,473, 32,468] Среднее значение 35,845

  new HappyPack({
            id: 'vue-loader',
            loaders: ['vue-loader'],
            threadPool: happyThreadPool,
            verbose: true
        })

        {
            test: /\.vue$/,
            include: srcPath,
            loader: 'happypack/loader?id=vue-loader'
        },

[37,683, 39,648, 35,499, 35,108, 37,419, 35,862] Среднее значение 36,869

 new HappyPack({
            id: 'css-loader',
            loaders: ['css-loader'],
            threadPool: happyThreadPool,
            verbose: true
        })

{
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                //'css-loader'
                'happypack/loader?id=css-loader'
            ]
        }

[39,394, 39,443, 35,080, 37,253, 37,501, 35,632] Среднее значение 37,383

[35,639, 36,382, 34,144, 33,420, 34,641, 32,504, 34,313] 34,434 Скорость стабильна в пределах 30-35, укорачивается примерно на 1-2 секунды.

3. Добавьте каталог кеша Babel.

4.devtool

devtool: 'исходная карта' Скорость сборки: 25.133, 26.545, 25.956, 24.763, 26.953 ~ 25.869 Скорость восстановления: 1,387, 1,632, 1,872, 1,809, 0,932 ~ 1,526

devtool скорость наращивания восстановить скорость Производственная среда качественный
eval 21.473 +++ 0.6822 +++ no сгенерированный код
cheap-eval-source-map 23.251 + 0.8622 ++ no Переведенный код (только строки)
cheap-module-eval-source-map 24.9536 o 1.124 ++ no Оригинальный исходный код (только строка)
eval-source-map 24.161 -- 0.9534 + no оригинальный исходный код

Суммировать

Окончательная скорость упаковки снижена с 60-70 до 30-35 с, сокращение составляет около 20-25 с, а скорость улучшения составляет около 30%. Скорость разработки Скорость вторичной упаковки снижена примерно с 2,7~2,9 с до 0,6~0,9 с, примерно на 2 с быстрее, примерно на 60%-70% быстрее devtoo: eval

Левое и правое уменьшаются до 0,8~1,3 с, среднее значение составляет 1,124, скорость составляет около 1 с, а скорость составляет около 35%.