Некоторый базовый метод оптимизации веб-пакета

Webpack

Оптимизация сборки

1. noParse (нет необходимости анализировать внутренне зависимые пакеты)

Для некоторых сторонних пакетов, которые мы представили, таких какjQuery, внутри эти пакеты точно не будут зависеть от других пакетов, поэтому нет необходимости в вебпаке парсить свои внутренние зависимости, которые можно найти вwebpackв файле конфигурацииmoduleдобавить в свойстваnoParseАтрибут, его значение представляет собой регулярное выражение, используемое для сопоставления модулей, которые не нуждаются в разборе, что позволяет сэкономитьwebpackсократить время упаковки и повысить эффективность упаковки.

module:{
    noParse:/jquery/
}

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

2. DllPlugin (динамически подключаемая библиотека)

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

DllpluginПлагин может помочь нам извлечь эти немодифицированные пакеты в качестве динамически подключаемых библиотек и сгенерирует файл с именем manifest.json, который используется для созданияDLLReferencePluginСопоставлены со связанными зависимостями.

кReactВозьмите в качестве примераDll

  1. Сначала создайтеReactИзвлечено как Dllwebpackконфигурационный файлwebpack.react.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
  mode: 'development',
  // 入口文件:将要配置成Dll的库放进来
  entry: {
    react: [
      'react'
    ]
  },
  // 输出文件
  output: {
    // 输出文件名
    filename: '[name]_dll.js',
    // 输出文件路径
    path: path.resolve(__dirname, '../dist'),
    // 将打包好的结果暴露在全局
    library: '[name]_dll'
  },
  plugins: [
    new webpack.DllPlugin({
      // dll文件名
      name: '[name]_dll',
      // 清单文件路径
      path: path.resolve(__dirname, '../dist/mainfest.json')
    })
  ]
}
  1. настроитьDllReferencePlugin

Этот плагин обычноwebpackНастроить в основном конфигурационном файле, вpluginsДобавьте следующую конфигурацию в конфигурацию,manifestфайл сопоставит приложение файла dll с модулемid, а затем цитировать, когда это необходимоDllдокумент.

new webpack.DllReferencePlugin({
  // (绝对路径) manifest (或者是内容属性)中请求的上下文
  context: __dirname,
  // 清单文件路径
  manifest: path.resolve(__dirname, '../dist/manifest.json')
})
  1. Построить затем бегиwebpack.react.jsКонфигурационный файл, в общем можно добавить команды запуска скрипта в package.json
scripts:{
    "build:react": "webpack --config ./build/webpack.react.js"
}

Запустите команду в командной строке, котораяdistсоздается в каталогеreactизDllфайл, также создастmainfest.jsonфайл, этот файл содержитimportа такжеrequireизrequestк модулюidотображение.DLLReferencePluginЭтот файл также будет упоминаться. Затем упакуйте его снова, он не будетreactПовторите упаковку, но непосредственно обратитесь к сгенерированномуreact_dllдокумент.

Оптимизация кода

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

1, веб-пакет поставляется с оптимизацией

ПучокwebpackизmodeУстановить какproduction, при упаковке в производственном режимеwebapckСледующие оптимизации выполняются автоматически

  • tree shaking

webpackУдаляет импортированный, но неиспользуемый код при упаковке, но только через модульную систему ES6.importПредставленный синтаксис будет применяться толькоtree shaking, уменьшите размер файла в производственной среде и автоматически реализуйте самую базовую оптимизацию

  • scope hoisting

Анализируйте зависимости между модулями и максимально объединяйте разбросанные модули в одну функцию. Следует отметить, что этот метод оптимизации также возможен только приES6в модульной системеimportМодули с введенным синтаксисом применимы, и только те модули, на которые есть ссылка только один раз, могут быть объединены.

  • сжатие кода

Все коды используются автоматическиUglifyJsPluginсжимать.

2, оптимизация CSS

  • Разделить CSS на отдельные файлы

mini-css-extract-pluginCSS можно разделить на отдельные файлы, чтобы файлы CSS можно было загружать асинхронно, что ускоряет загрузку и отрисовку страницы.

Инструкции:

  1. Установить плагин
$ npm i mini-css-extract-plugin -D
  1. Измените основной файл конфигурации, чтобы использовать плагин
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
    ...,
    module: {
        rules: [
            ...,
            {
                test: /\.css$/,
                // 将原来多有使用style-loader来处理的地方替换为使用MiniCssExtractPlugin.loader
                // use: ['style-loader', 'css-loader'],
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            }
        ]
    },
    plugins: [
        ...,
        new MiniCssExtractPlugin({
            // 生成的文件名
            filename: '[name].css'
        })
    ]
}
  • Сжать CSS

optimize-css-assets-webpack-pluginМожет использоваться для сжимания файла CSS, но с использованием плагина приведет к подключаемую конфигурацию сжатия JS WebPack по умолчанию.terser-webpack-plugin

Инструкции:

  1. Установить плагин
$ npm i optimize-css-assets-webpack-plugin terser-webpack-plugin -D
  1. Измените основной файл конфигурации, чтобы использовать плагин
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = {
    ...,
    optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
    }
}

3. JS-оптимизация

  • Разделить общий код

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

Optimization: {
    splitChunks: {
        Chunks: 'all'
    }
}
  • IgnorePlugin (игнорировать плагин)

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

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

// 该方法的两个参数都是正则,第一个参数表示要忽略的路径,第二个表示该资源所在目录,在该文件夹下引入的语言包都会被忽略
new webpack.IgnorePlugin(/\.\/locale/, /moment/)

В настоящее время момент использует английский язык по умолчанию.Если вы хотите использовать другой язык, вы можете вручную импортировать языковой пакет, который вам нужен.

import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-CN')
  • ленивая загрузка

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

// 假设在页面中有一个id为btn的按钮,当点击这个按钮的时候需要对时间进行操作
const btn = document.querySelector('#btn')
btn.onclick = e => import(/* webpackChunkName: "moment" */ 'moment').then(module => {
    var moment = module.default;
    moment().format('YYYY-MM-DD')
})

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

const btn = document.querySelector('#btn')
btn.onclick = e => import(/* webpackChunkName: "moment" *//* webpackPrefetch: true */ 'moment').then(module => {
    var moment = module.default;
    moment().format('YYYY-MM-DD')
})

держать в курсе

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