← Назад к вопросам

Вводил ли оптимизации bundle на этапе сборки

1.3 Junior🔥 231 комментариев
#Инструменты и DevOps#Оптимизация и производительность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Оптимизация Bundle на этапе сборки

Оптимизация bundle (сборки) на этапе сборки — критически важный процесс для улучшения производительности веб-приложений. Правильно настроенная сборка может значительно снизить размер финального бандла и время загрузки страницы.

Основные метрики оптимизации

Перед началом оптимизации нужно понимать ключевые метрики:

  • Bundle size — размер финального bundle (главная метрика)
  • Initial JS — размер JavaScript, загружаемого при первой загрузке
  • Chunk size — размер отдельных chunks (для code splitting)
  • Time to Interactive (TTI) — время до интерактивности приложения

1. Tree Shaking - удаление неиспользуемого кода

Tree shaking автоматически удаляет неиспользуемый код из bundle.

// math.js - экспортируем несколько функций
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

export function multiply(a, b) {
  return a * b;
}

// app.js - используем только add
import { add } from './math.js';

console.log(add(2, 3)); // 5

// При сборке subtract() и multiply() будут удалены (tree shaken)

Как настроить в webpack:

// webpack.config.js
module.exports = {
  mode: 'production', // включает tree shaking по умолчанию
  optimization: {
    usedExports: true,
    sideEffects: false // указывает, что код не имеет побочных эффектов
  }
};

package.json:

{
  "sideEffects": false,
  "main": "index.js",
  "module": "index.esm.js"
}

2. Code Splitting - разделение кода на части

Вместо одного большого bundle создаются несколько меньших chunks, которые загружаются по требованию.

Динамический импорт:

// Вместо статического импорта
// import HeavyComponent from './HeavyComponent';

// Используем динамический импорт
function loadComponent() {
  return import('./HeavyComponent').then(module => module.default);
}

// В React
import { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

Route-based splitting в Next.js:

// pages/dashboard.tsx
import dynamic from 'next/dynamic';

const Dashboard = dynamic(() => import('../components/Dashboard'), {
  ssr: false, // отключить server-side rendering
  loading: () => <div>Loading...</div>
});

export default Dashboard;

Webpack configuration:

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\/]node_modules[\/]/,
          name: 'vendors',
          priority: 10,
        },
        common: {
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

3. Minification и Compression

Минификация удаляет ненужные символы из кода.

// Исходный код
const calculateSum = (arrayOfNumbers) => {
  let total = 0;
  for (let i = 0; i < arrayOfNumbers.length; i++) {
    total = total + arrayOfNumbers[i];
  }
  return total;
};

// После minification
const calculateSum=(a)=>{let t=0;for(let i=0;i<a.length;i++)t+=a[i];return t};

Webpack настройка:

module.exports = {
  mode: 'production',
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // удалить console.log
          },
        },
      }),
    ],
  },
};

4. Анализ Bundle - определение проблем

# Установить анализатор
npm install --save-dev webpack-bundle-analyzer

# Использовать в webpack
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
};

Вывод анализатора:

- node_modules: 450 KB (самая большая часть)
  - react: 120 KB
  - lodash: 70 KB (используется только 5% функций!)
  - moment: 60 KB (заменить на date-fns)

- src: 150 KB
  - App.js: 50 KB (много статических данных)
  - components: 100 KB

5. Практические примеры оптимизации

Пример 1: Замена тяжелой библиотеки

// Плохо: moment.js = 60 KB
import moment from 'moment';
const date = moment().format('YYYY-MM-DD');

// Хорошо: date-fns = 10 KB
import { format } from 'date-fns';
const date = format(new Date(), 'yyyy-MM-dd');

Пример 2: Удаление неиспользуемого CSS

// tailwind.config.js
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
  ],
  // Это удалит все неиспользуемые Tailwind классы
};

Пример 3: Lazy loading изображений

// Не оптимально
import logo from './logo.png';

function Header() {
  return <img src={logo} alt="Logo" />;
}

// Оптимально с Next.js Image
import Image from 'next/image';
import logo from './logo.png';

function Header() {
  return (
    <Image
      src={logo}
      alt="Logo"
      placeholder="blur"
      priority={false}
    />
  );
}

6. Метрики и мониторинг

// package.json scripts
{
  "scripts": {
    "build:analyze": "webpack --mode=production && webpack-bundle-analyzer dist/stats.json",
    "build:report": "webpack --profile --json > dist/stats.json",
    "lighthouse": "lighthouse https://example.com --output-path=./report.html"
  }
}

7. Сравнение инструментов сборки

ИнструментBundle SizeСкоростьКонфигурация
WebpackОптималенСредняяСложная
ViteХорошийВысокаяПростая
esbuildОтличныйОчень высокаяСредняя
ParcelХорошийСредняяМинимальная
Next.jsОтличныйВысокаяВстроенная

8. Типичные ошибки

Ошибка 1: Импорт целой библиотеки вместо модулей

// Плохо: импортируем весь lodash (70 KB)
import _ from 'lodash';
const unique = _.uniq([1, 2, 2, 3]);

// Хорошо: импортируем только нужную функцию
import uniq from 'lodash/uniq';
const unique = uniq([1, 2, 2, 3]);

Ошибка 2: Забыли про sideEffects в package.json

{
  "sideEffects": false // ОБЯЗАТЕЛЬНО для tree shaking!
}

Ошибка 3: Дублирование зависимостей

# Проверить дубликаты
npm ls lodash

# Удалить дубликаты
npm dedupe

Чеклист оптимизации bundle

  • Включена минификация и сжатие (gzip/brotli)
  • Настроен tree shaking (usedExports: true)
  • Настроен code splitting для динамических импортов
  • Разделены vendor и application code
  • Анализирован bundle размер (webpack-bundle-analyzer)
  • Удалены неиспользуемые зависимости
  • Заменены тяжелые библиотеки на более легкие альтернативы
  • Настроена компрессия на сервере
  • Включен lazy loading для компонентов и изображений
  • Мониторится размер bundle в CI/CD

Оптимизация bundle — это непрерывный процесс, требующий постоянного мониторинга и улучшений.

Вводил ли оптимизации bundle на этапе сборки | PrepBro