На изображении показан титульный слайд моего доклада, на котором повторяется тема (Как готовить файлы для production?) и моё имя (Алекс Рассудихин).

Как готовить файлы для production?


AlmatyJS Light #6

1 апреля 2025 года в рамках конференции “AlmatyJS Light #6” я представил доклад о том, что нужно сделать с файлами перед отправкой их на production к пользователям.

В презентации я рассмотрел основные аспекты оптимизации файлов для production, такие как:

  • Оптимизация размеров HTML, CSS и JavaScript файлов, хоть и упомянул это вскользь, потому как чаще всего все оптимизации готовы на стороне bundler-а;
  • Оптимизация изображений: выбор формата изображений (webp или avif) и дал общие рекомендации по работе с изображениями в проекте;
  • Оптимизация шрифтов: выбор шрифта и чем woff2 лучше, чем любой другой формат шрифта в 2025, а также пара советов как сэкономить на спичках в шрифтах;
  • Оптимизация SVG: использование спрайтов и чем они лучше любых других вариантов подключения SVG-иконок к странице.

В докладе я говорил о том, что для спрайтов и отдельных SVG-файлов я писал конфиг для webpack, который позволяет сжимать иконки эффективно. В моём случае всё было реализовано на Next.js 14, его конфиг и прикреплю ниже:

const spritePlugins = [
  'cleanupAttrs',
  'cleanupEnableBackground',
  'cleanupListOfValues',
  'cleanupNumericValues',
  'collapseGroups',
  'removeUselessStrokeAndFill',
  'removeNonInheritableGroupAttrs',
  'removeEmptyAttrs',
  'removeEmptyContainers',
  'removeEmptyText',
  'removeMetadata',
  'removeComments',
  'removeDesc',
  'mergeStyles',
  'minifyStyles',
  'convertEllipseToCircle',
  'convertOneStopGradients',
  'convertPathData',
  'convertShapeToPath',
  'convertStyleToAttrs',
  'removeXMLProcInst',
];

const svgFilesPlugins = [
  'cleanupAttrs',
  'cleanupEnableBackground',
  'cleanupListOfValues',
  'cleanupNumericValues',
  'collapseGroups',
  'removeUselessStrokeAndFill',
  'removeNonInheritableGroupAttrs',
  'removeEmptyAttrs',
  'removeEmptyContainers',
  'removeEmptyText',
  'removeMetadata',
  'removeComments',
  'removeDesc',
  'mergeStyles',
  'minifyStyles',
  'convertEllipseToCircle',
  'convertOneStopGradients',
  'convertPathData',
  'convertShapeToPath',
  'convertStyleToAttrs',
  'cleanupIds',
  'convertColors',
  'moveElemsAttrsToGroup',
  'removeDimensions',
  'removeDoctype',
  'removeEditorsNSData',
  'removeHiddenElems',
  'removeTitle',
  'removeUselessDefs',
];

webpack(config) {
  config.module.rules.push({
    test: /\.svg$/,
    oneOf: [
      {
        test: /\.sprite\.svg$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'static/media/[name].[hash].[ext]',
            },
          },
          {
            loader: 'svgo-loader',
            options: {
              plugins: spritePlugins,
            },
          },
        ],
      },
      {
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'static/media/[name].[hash].[ext]',
            },
          },
          {
            loader: 'svgo-loader',
            options: {
              plugins: svgFilesPlugins,
            },
          },
        ],
      },
    ],
  });

  return config;
}

Презентация и дополнительные материалы доступны по ссылкам ниже.

© 2025 Рассудихин Алекс