Разделение кода Webpack влияет на производительность сети - PullRequest
5 голосов
/ 10 июля 2020

У меня есть приложение React / Node + SSR, я пытаюсь создать производственную сборку, мне это удалось, но проблема в том, что файлы, которые у меня есть в сборке, слишком велики. Я использую последнюю версию react + webpack 4. Вот моя конфигурация webpack:

clientConfig. js

const path = require('path');
const common = require('./webpack.common-config');

const clientConfig = {
  ...common,
  mode: 'production',
  name: 'client',
  target: 'web',
  devtool: false,
  entry: {
    client: [
      '@babel/polyfill',
      './src/client.js'
    ],
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].js',
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          chunks: 'all',
          name: 'vendor',
          test: module => /node_modules/.test(module.resource),
          enforce: true
        },
        common: {
          chunks: 'all',
          name: 'client'
        }
      },
    },
  },
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
  }
};

module.exports = clientConfig;

serverConfig. js

const nodeExternals = require('webpack-node-externals');
const path = require('path');
const common = require('./webpack.common-config');

const serverConfig = {
  ...common,
  mode: 'production',
  name: 'server',
  target: 'node',
  devtool: false,
  externals: [nodeExternals()],
  entry: {
    server: ['@babel/polyfill', path.resolve(__dirname, 'src', 'server.js')],
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
    }
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].js',
    chunkFilename: "[id].chunk.js"
  },
  node: {
    console: false,
    global: false,
    process: false,
    Buffer: false,
    __filename: false,
    __dirname: false,
  },
};

module.exports = serverConfig;

commonConfig. js

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

const common = {
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        include: [path.resolve(__dirname, 'src')],
        query: {
          presets: [
            ['@babel/preset-env', {loose: true, modules: false}],
            "@babel/preset-react"
          ],
          plugins: [
            "@babel/plugin-proposal-class-properties"
          ]
        },
      },
      {
        test: /\.css$/,
        use: [
            {
                loader: MiniCssExtractPlugin.loader,
            },
            'css-loader'
        ]
      },
      {
        test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new OptimizeCSSAssetsPlugin(),
    new MiniCssExtractPlugin({
      filename: "styles.css",
    })
  ],
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()]
  },
};

module.exports = common;

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

Я запускаю npm run build, после этого запускаю webpack -p --mode=production --optimize-minimize && node ./build/server.js

Я получаю следующее предупреждение:

    WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
    This can impact web performance.
    Assets: 
      vendor.js (667 KiB)
    
    WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
    Entrypoints:
      client (928 KiB)
          vendor.js
          styles.css
          client.js

Любые советы или идеи по поводу вышеуказанного предупреждения о размере были бы замечательными! Спасибо!

Ответы [ 3 ]

4 голосов
/ 11 июля 2020

Я рекомендую вам попробовать core-js вместо babel/pollyfill, это может помочь вам уменьшить размер пакета.

Кроме того, я рекомендую вам попробовать динамический импорт c с react-loadable, который поддерживает ССР. существуют разные стратегии разделения вашего кода. вы можете прочитать больше здесь (самый важный)

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

Если вы используете такие библиотеки, как loda sh или материал -ui вы должны импортировать свой модуль специально, чтобы избежать импорта всех пакетов в свой пакет.

exp: import debounce from 'lodash/debounce'

npm dedup или yarn dedup может помочь удалить повторяющиеся зависимости внутри пакета .

0 голосов
/ 20 июля 2020

Вы можете разделить файлы на меньший размер, чтобы удалить предупреждение, используя splitChunks :

optimization: {
      splitChunks: {
        chunks: 'all',
        minSize: 10000,
        maxSize: 250000,
      }
    }

Проверьте больше для minSize и maxSize .

Если вы хотите отключить предупреждение, вы можете сделать это с помощью performance

performance: {
  hints: false
}

или удалить предупреждение для определенного ограничения размера, например 1 МБ:

performance: {
  maxAssetSize: 1000000
}
0 голосов
/ 20 июля 2020

Возможно, вы сможете получить некоторое сокращение, изменив конфигурацию babel. Например, указав некоторые параметры для «preset-env», такие как исправления , targets, если у вас нет поддержки старых браузеров, и использование полифиллов corejs вместо babel/polyfill.

"@babel/preset-env", {
  "targets": {
    "browsers": [
      "last 2 years"
    ]
  },
  "bugfixes": true,
  "useBuiltIns": "entry",  // experiment with "entry" vs. "usage"
  "corejs": 3
...

В зависимости от вашей кодовой базы babel-plugin-transform-runtime тоже может помочь. У меня было несколько проектов, в которых это существенно изменилось, но в других - нет.

"@babel/plugin-transform-runtime",
{
  "corejs": 3,
  "version": "7.9.2"
}

Дополнительные параметры для Webpack включают использование webpack-cdn-plugin . Это может значительно уменьшить размер пакета вашего поставщика. Конечно, пользователям все равно придется загружать те же библиотеки, но они будут кэшироваться, и их не нужно будет повторно загружать каждый раз при изменении или обновлении вашего пакета.

Небольшую дополнительную экономию можно получить, указав runtimeChunk: true и, возможно, встраивание этого фрагмента в ваш индекс. html с

new HTMLWebpackPlugin({
  inlineSource: 'runtime~.+[.]js',
  ...

и html -webpack-inline-source-plugin или аналогичным.

...