Как стать автором
Обновить
Контур
Делаем сервисы для бизнеса

Как мы мертвый код убивали

Уровень сложностиПростой
Время на прочтение3 мин
Количество просмотров2.2K

В апреле я съездил на HolyJS. Еще до поездки в расписании конференции моё внимание привлек доклад Виктора Хомякова «Удаление мертвого кода в проекте: практическое руководство». Послушав его, я понял, что могу использовать полученные знания в своем текущем проекте, при этом не затрачивая много усилий. В этой статье я расскажу, что у меня получилось.

Что такое мертвый код

Мертвый код — это участки кода или зависимостей, которые:

  • Никогда не выполняются

  • Не используются нигде в проекте

  • Включают ненужные пакеты и дубли транзитивных зависимостей (например, пакеты в dependencies)

  • Невозможно выполнить

import someLib from 'someLib';
 
if (Math.random() > 1) {
    someLib.doSomething(); 
}

Какой план

Мы решили заняться оптимизацией производительности нашего приложения в три этапа:

  1. Анализ производительности — оценка текущего веса и скорости приложения

  2. Удаление мертвого кода

  3. Автоматизация — внедрение автоматизированных процессов для оптимизации

Анализ производительности

Наше приложение собирается при помощи webpack. Для анализа бандлов использовал webpack-bundle-analyzer. Результаты получились следующие:

  • Время сборки: 10–16 минут.

  • Проблема: серверный бандл содержит шрифтовые ассеты.

Удаление мертвого кода

Бандл проанализировали, печальные выводы сделали. Переходим к практике!

Дедуплиĸация npm

Пакетный менеджер у нас npm. Поэтому вот что я делал:

  • Диагностировал через команды

npm list --include=prod 
npm find-dupes
  • Устранил дубли

npm dedupe 
 
added  28  packages ,  removed  57  packages , ¨NBSP; and  changed  117  packages  in  20s
  • Сказал команде поправить конфиг npm

npm config set prefer-dedupe true

Настройки ESLint и tsconfig

В .eslintrs добавлены правила:

"no-unused-vars": "error",
"no-unused-private-class-members": "error",
"no-unreachable": "error",
"no-unused-expressions": "error"

А в tsconfig.json добавлено:

"noUnusedLocals": true /* Enable error reporting when a local variables aren't read. */,
"noUnusedParameters": true /* Raise an error when a function parameter isn't read */,

Настройка knip и удаление мертвечины

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

Помимо knip рассматривал ts-prune и TSR, но первый больше не развивается, а у второго мне не хватило более тонкой настройки конфигурации.

Результаты проверки knip

Выглядит НЕ круто!

Фиксим

Сначала разобрался с зависимостями, затем пришлось править конфиг knip, добавлять новые точки входа, игноры. Итоговый knip.json вышел таким:

{
    "$schema": "https://unpkg.com/knip@5/schema.json",
    "entry": ["src/client/index.tsx", "src/server/server.js", "bin/dev.js", "jest.config.js", "jest.setup.js"],
    "project": ["src/**/*.{ts,tsx,js,jsx,mjs}"],
    "ignore": ["**/*.global.css", "**/*.td.ts", "**/index.ts"],
    "webpack": {
        "config": ["webpack.config.js", "cfg/webpack.client.config.js", "cfg/webpack.server.config.js"]
    },
    "babel": {
        "config": ["babel.config.js"]
    },
    "ignoreDependencies": [
        "enzyme",
        "enzyme-to-json",
        "@types/enzyme",
        "@types/react-router-dom",
        "prettier",
        "prettier-eslint"
    ]
}

Потом разрешил удалять неиспользуемые файлы. Реализуется через scripts в package.json:

"knip": "knip",
"knip:md": "knip --reporter markdown > knip-report.md",
"knip:fix": "knip --fix-type exports,types,files --allow-remove-files"

knip:md формирует отчет в .md формате.knip:fix позволяет knip фиксить обнаруженные проблемы. Флаг --allow-remove-files дает удалять неиспользуемые файлы.

В результате проделанных действий все проблемы, что выявил knip, были решены.

Что дальше:

  • Запихнуть проверку knip в pre commit hooks.

  • В knip.json добавлены '**/index.ts' в игнор. Нужно правильно обрабатывать такие файлы.

Итоги

Папка

До оптимизации

После оптимизации

Разница (МБ)

Разница (%)

node_modules

825M

669M

-156M

▼ 18.90%

dist

12.8M

8.0M

-4.8M

▼ 37.50%

client

7.1M

5.9M

-1.2M

▼ 16.90%

server

5.7M

2.1M

-3.6M

▼ 63.16%

Раньше приложение на поде поднималось 10-16 минут, теперь за 3–7 минут.

Теги:
Хабы:
+14
Комментарии8

Публикации

Информация

Сайт
tech.kontur.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия
Представитель
Варя Домрачева