О точках оптимизации упаковки конфигурации vue-cli 3

оптимизация производительности

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

  • Настройка маршрутизации ленивая загрузка, метод инкапсулирующих компонентов, представленных асинхронным приемным адресом в качестве аргумента
/**
 *  返回异步组件
 * @tips 请注意页面只能挂载在views文件下,非此路径请勿使用
 */
const AsyncComponentHook = (path: String): Function => (): any => {
    // 通过 webpack 的内联注释,设置模块名
    let component = import(/* webpackChunkName: "view-[request]" */ `@/views/${path}.vue`);
    component.catch((e) => {
        console.error(e);
    });
    return component;
};
  • Настроить сжатие кода
    // 安装
    npm install uglifyjs-webpack-plugin

    // 在vue.config.js文件中添加配置
    configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            // 为生产环境修改配置...
            config.plugins.push(
                //生产环境自动删除console
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            warnings: false,
                            drop_debugger: true,
                            drop_console: true,
                        },
                    },
                    sourceMap: false,
                    parallel: true,
                })
            );
        }
    },

  • Настроить ссылочные псевдонимы

  • Настройте внедрение плагинов по запросу, в этой статье используетсяelement-ui,Нажми для деталей

...

После некоторой базовой настройки давайте посмотрим на текущий эффект упаковки.

Как видно из рисунка ниже, самая большая упаковка после расфасовки1.33M. Потом еще раз посмотри на запрос, вау,217запросы, требуется загрузка домашней страницы3.2M.

预览图 预览图

...

Ладно, начинай кидать

1. Оптимизация внедрения файлов конфигурации scss

В процессе сборки проекта мы часто извлекаем некоторые файлы конфигурации scss, такие как цвета темы и т. д., а затем внедряем их в каждый необходимый компонент. Это будет очень громоздко, мы можем использовать sass-loader, чтобы помочь нам с предварительной обработкой, Таким образом, нам не нужно импортировать стили на каждую страницу, мы можем напрямую ссылаться на них.

Например, в нашем каталоге файлов стилей есть файл theme.scss, мы можемvue.config.jsиметь дело со следующим

// vue.config.js 配置
module.exports = {
  css: {
    // css预设器配置项
    loaderOptions: {
        // pass options to sass-loader
        sass: {
            // 引入全局变量样式,@使我们设置的别名,执行src目录
            data: `
                @import "@/stylePath/theme.scss";
            `
        }
    },
  },
}

С помощью приведенной выше конфигурации вы можете аннотировать следующий код в шаблоне компонента.

<style lang="scss">
   /* @import "@/stylePath/theme.scss"; */
</style>

2. Оптимизируйте количество запросов

Мы обнаружили, что количество запросов увеличилось, потому что наша страница предварительно отрисовывала другие компоненты, которые вставляли что-то подобное в html-страницу.<link rel="prefetch">, как это оптимизировать?

Сначала давайте посмотрим наvue.config.jsОфициальная документация ,Нажмите, чтобы перейти. Официальное описание: это подсказка ресурса, которая используется для указания браузеру использовать время простоя для получения контента, к которому пользователь может получить доступ в будущем после загрузки страницы.

Итак, мы добавляем следующую конфигурацию

// vue.config.js
module.exports = {
  chainWebpack: config => {
    // 移除 prefetch 插件
    config.plugins.delete('prefetch')
    // 移除 preload 插件
    config.plugins.delete('preload');
  }
}

3. Общее извлечение кода, используйте cdn для загрузки

дляvue, vuex, vue-router,axiosпока мы не сможем использоватьwenpackизexternalsПараметры для настройки, здесь мы устанавливаем, это нужно использовать только в производственной среде:

// vue.config.js
const isProduction = process.env.NODE_ENV === 'production';
const cdn = {
    css: [],
    js: [
        'https://cdn.bootcss.com/vue/2.5.17/vue.runtime.min.js',
        'https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js',
        'https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js',
        'https://cdn.bootcss.com/axios/0.18.0/axios.min.js',
    ]
}
module.exports = {
    chainWebpack: config => {
        // 生产环境配置
        if (isProduction) {
            // 生产环境注入cdn
            config.plugin('html')
                .tap(args => {
                    args[0].cdn = cdn;
                    return args;
                });
        }
    },
    configureWebpack: config => {
        if (isProduction) {
            // 用cdn方式引入
            config.externals = {
                'vue': 'Vue',
                'vuex': 'Vuex',
                'vue-router': 'VueRouter',
                'axios': 'axios'
            }
        }
    },
}

Затем изменитеhtmlфайл, добавить код инъекции

<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <!-- 使用CDN的CSS文件 -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
  <% } %>
  <!-- 使用CDN的JS文件 -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
    <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
  <% } %>
</head>

<body>
  <noscript>
    <strong>We're sorry but eye-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
  <!-- built files will be auto injected -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
  <% } %>
</body>

</html>

Затем упакуйте и перезапустите, давайте посмотрим на текущие изменения.

Ну, это действительно ароматно~ Как вы можете видеть на картинке ниже, самый большой файл пакета после упаковки составляет всего лишь775kb. Потом еще раз посмотри на запрос, вау,43запросы и загрузка домашней страницы требуют только1.4M.

Видно, что количество запросов после нашей серии операций уменьшилось174, рендеринг главной страницы уменьшен1.8m, какая радость

预览图 预览图

Наконец, прикрепите полныйvue-config.jsдокумент

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

const isProduction = process.env.NODE_ENV === 'production';
const cdn = {
    css: [],
    js: [
        'https://cdn.bootcss.com/vue/2.5.17/vue.runtime.min.js',
        'https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js',
        'https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js',
        'https://cdn.bootcss.com/axios/0.18.0/axios.min.js',
    ]
}

function resolve(dir) {
    return path.join(__dirname, dir)
}

module.exports = {
    // 基本路径
    baseUrl: './',
    // 输出文件目录
    outputDir: 'dist',
    // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
    // assetsDir: "./",
    // 指定生成的 index.html 的输出路径 (相对于 outputDir)。也可以是一个绝对路径
    indexPath: './',
    // eslint-loader 是否在保存的时候检查
    lintOnSave: true,
    // webpack配置
    // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
    chainWebpack: config => {
        config
            .entry('index')
            .add('babel-polyfill')
            .end();
        // 配置别名
        config.resolve.alias
            .set("@", resolve("src"))
            .set("@img", resolve("src/assets/images"))
            .set("@css", resolve("src/assets/styles/css"))
            .set("@scss", resolve("src/assets/styles/scss"));
        // 生产环境配置
        if (isProduction) {
            // 删除预加载
            config.plugins.delete('preload');
            config.plugins.delete('prefetch');
            // 压缩代码
            config.optimization.minimize(true);
            // 分割代码
            config.optimization.splitChunks({
                chunks: 'all'
            })
            // 生产环境注入cdn
            config.plugin('html')
                .tap(args => {
                    args[0].cdn = cdn;
                    return args;
                });
        }
    },
    configureWebpack: config => {
        if (isProduction) {
            // 用cdn方式引入
            config.externals = {
                'vue': 'Vue',
                'vuex': 'Vuex',
                'vue-router': 'VueRouter',
                'axios': 'axios'
            }
            // 为生产环境修改配置...
            config.plugins.push(
                //生产环境自动删除console
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            warnings: false,
                            drop_debugger: true,
                            drop_console: true,
                        },
                    },
                    sourceMap: false,
                    parallel: true,
                })
            );
        } else {
            // 为开发环境修改配置...
        }
    },
    // 生产环境是否生成 sourceMap 文件
    productionSourceMap: false,
    // css相关配置
    css: {
        // 是否使用css分离插件 ExtractTextPlugin
        extract: true,
        // 开启 CSS source maps?
        sourceMap: false,
        // css预设器配置项
        loaderOptions: {
            // pass options to sass-loader
            sass: {
                // 引入全局变量样式
                data: `
                    @import "@/stylePath/theme.scss;
                `
            }
        },
        // 启用 CSS modules for all css / pre-processor files.
        modules: false,
    },
    // use thread-loader for babel & TS in production build
    // enabled by default if the machine has more than 1 cores
    parallel: require('os').cpus().length > 1,
    devServer: {
        port: 8888,  // 端口
        open: true, // 自动开启浏览器
        compress: false, // 开启压缩
        overlay: {
            warnings: true,
            errors: true
        }
    },
}

Выше приведена оптимизация, которую я сделал после упаковки, конечно есть и другие моменты оптимизации, такие как открытиеgzipСжатие, но для этого требуется поддержка фонового сервера, поэтому пока не настраивается. Если у вас есть другие моменты оптимизации, добро пожаловать к совместному обсуждению!

Автор этой статьи: Эчи
Ссылка на эту статью:Талант /user/729731…
Заявление об авторских правах: если не указано иное, в этой статье используется@BY-NC-SAсоглашение. Пожалуйста, укажите источник!