Джанк в разработке — что это, чем вреден junk-код и как убирать

Автор: IT Sectr Опубликовано: 2026-07-27 Время чтения: 10 мин

Джанк (junk code) — это код и зависимости, которые не приносят пользы проекту, но увеличивают его объём, время сборки и когнитивную нагрузку на команду. В отличие от мёртвого кода, который никогда не выполняется, джанк может работать, но делает это неэффективно или избыточно: дублирующие библиотеки, неиспользуемые импорты, закомментированные блоки, устаревшие polyfill-ы и декоративные абстракции. По данным отчёта CodeScene Code Health Report (2025), в среднем 15 процентов зависимостей в мобильных проектах не используются напрямую, а только тянут транзитивные пакеты. Junk-код — это «лишний вес» проекта: он делает кодбазу толще, но не сильнее. Регулярный аудит зависимостей и удаление избыточных абстракций напрямую улучшают скорость сборки и качество кода.

Главное

  • Джанк — бесполезный или избыточный код и зависимости, увеличивающие размер проекта без пользы.
  • Виды джанка: мёртвые зависимости, дублирующие библиотеки, закомментированный код, пустые абстракции.
  • Junk-зависимости увеличивают surface area для атак и замедляют CI-пайплайн.
  • Инструменты аудита: Gradle dependencies (Android), SwiftPM audit (iOS), depcheck (Node.js).
  • Регулярная чистка джанка — такая же часть техподдержки проекта, как написание нового кода.

Что такое джанк?

Джанк (junk code) — собирательный термин для кода, конфигураций и зависимостей, которые присутствуют в проекте, но не несут функциональной ценности. Джанк не обязательно сломан или неиспользуем — проблема в том, что его наличие ухудшает метрики проекта без адекватного оправдания.

Джанк делится на четыре категории. Первая — избыточные зависимости: библиотеки, подключённые для одной функции, которую можно реализовать стандартными средствами. Вторая — мёртвый груз: закомментированные блоки, TODO без тикетов, пустые методы и классы-заглушки. Третья — дублирующие решения: две библиотеки, делающие одно и то же (например, Gson и Kotlin Serialization в одном проекте). Четвёртая — овер-инжиниринг: архитектурные прослойки, которые не используются, но поддерживаются «на будущее».

По данным исследования Stripe Engineering Productivity (2025), удаление 10 процентов джанка из типичного проекта сокращает время полной сборки в среднем на 22 процента. Причина: каждая лишняя зависимость увеличивает граф сборки, каждая пустая абстракция требует времени на понимание, каждый закомментированный блок отвлекает внимание.

Главная сложность в борьбе с джанком — отсутствие немедленных последствий. Проект с junk-кодом компилируется и работает. Проблемы накапливаются постепенно: сборка замедляется, количество transitive dependencies растёт, а через год добавить новую фичу становится в два раза дольше, чем должно быть.

Junk-зависимости и как их выявлять

Junk-зависимости — это библиотеки и пакеты, которые подключены к проекту, но не используются напрямую в коде, либо используются лишь в одной функции, которую проще реализовать на стандартных API.

Типичные примеры: библиотека для работы с JSON, когда проект уже использует Kotlin Serialization (два парсера — это джанк); библиотека Apache Commons Lang для одного метода StringUtils.isEmpty, который заменяется Kotlin extension isNullOrBlank; библиотека для DI, которая используется в одном модуле из десяти, а остальные получают зависимости через конструктор вручную.

Каждая лишняя зависимость — это не только лишний код в бинарнике. Это увеличение surface area для уязвимостей: по данным GitHub Advisory Database (2025), 40 процентов критических CVE в мобильных проектах приходятся на транзитивные зависимости, которые разработчики не контролируют. Чем меньше зависимостей — тем меньше поверхность атаки.

Анализ зависимостей Android-проекта

groovy
// View Gradle dependency tree
./gradlew app:dependencies --configuration releaseRuntimeClasspath

// Find unused dependencies (Gradle plugin)
plugins {
    id "com.autonomousapps.dependency-analysis" version "2.0.0"
}

// Generate unused library report
./gradlew buildHealth

Для iOS используйте команду swift package show-dependencies, которая выводит полное дерево зависимостей. Инструмент Xcode Build Timeline показывает, сколько времени каждая библиотека добавляет к сборке. Если библиотека занимает 30 процентов времени компиляции, но используется в одном экране — это кандидат на удаление или замену.

Для Node.js (React Native) используйте depcheck — утилиту, которая находит неиспользуемые зависимости в package.json, и npm-check, которая дополнительно показывает устаревшие версии. Внедрите правило: каждая новая зависимость проходит code review с обоснованием «почему нельзя стандартными средствами».

Мёртвые импорты и закомментированный код

Мёртвые импорты — самый распространённый вид джанка. Они не влияют на рантайм, но увеличивают время компиляции: компилятор обрабатывает каждый импорт, даже если он не используется. В больших проектах удаление неиспользуемых импортов сокращает время сборки на 5–10 процентов.

Современные IDE автоматически подсвечивают неиспользуемые импорты серым цветом. Настройте авто-очистку на сохранение файла: в IntelliJ IDEA — Optimize Imports on the fly, в Xcode — Editor > Remove Unused Imports. В CI добавьте проверку: линтер должен блокировать коммиты с неиспользуемыми импортами.

Закомментированный код — ещё один вид джанка. Разработчики комментируют блоки, чтобы «не потерять» функциональность при рефакторинге. Однако git хранит полную историю изменений: любой удалённый код можно восстановить за одну команду git revert или git log -S . Закомментированный код в master — это неуважение к команде: каждый разработчик тратит умственную энергию на вопрос «а зачем это закомментировано и когда надо раскомментировать».

Правило: в репозитории нет закомментированного кода. Если код не нужен — удалите его навсегда. Если код нужен, но временно отключён — используйте feature toggle с тикетом и сроком. Комментарии вида // TODO: remove after migration — не оставляйте без дедлайна. Поставьте дату и напомните себе календарём.

Избыточные абстракции и овер-инжиниринг

Овер-инжиниринг — создание архитектурных прослоек, которые не решают текущих проблем, но требуют поддержки. Это один из самых сложных видов джанка, потому что формально код «правильный»: он следует SOLID, покрыт тестами и соответствует архитектуре. Проблема в том, что он не нужен.

Классический пример — абстрактный класс UseCase с одним методом invoke, который просто вызывает репозиторий. Если UseCase не добавляет логики (кэширование, retry, трансформация), а только передаёт вызов дальше — это лишняя сущность. Она увеличивает навигацию по проекту: разработчик открывает UseCase, смотрит, что там invoke → repository — и закрывает. Время потрачено, пользы ноль.

Другой пример — избыточная параметризация. Generic-интерфейс с шестью type parameters, который используется в одном месте. Каждый type parameter — это когнитивная нагрузка: при чтении кода нужно держать в голове шесть типов, хотя реально используются только два. Если абстракция не переиспользуется — она избыточна.

Критерий отсечения: если абстракция не переиспользуется в трёх разных контекстах — удаляйте её. Абстракция оправдана, когда она реально решает проблему дублирования, а не прогнозирует гипотетические сценарии будущего. YAGNI (You Ain't Gonna Need It) — лучший принцип профилактики овер-инжиниринга.

Инструменты аудита джанка

Аудит джанка требует комбинации статического анализа, анализа зависимостей и ручной проверки. Полностью автоматизировать поиск избыточных абстракций нельзя, но технический джанк (мёртвые импорты, неиспользуемые библиотеки, закомментированный код) находится инструментами.

КатегорияИнструментЧто проверяет
Неиспользуемые зависимостиdependency-analysis (Gradle)Библиотеки, которые не используются в коде
Неиспользуемые зависимостиdepcheck (Node.js)Пакеты из package.json без импортов
Неиспользуемые зависимостиswift package --show-dependenciesДерево зависимостей SwiftPM
Мёртвые импортыIDE (Optimize Imports)Неиспользуемые import-выражения
Закомментированный кодgrep -r "//" / rg "^\s*//"Блоки комментариев с кодом
Пустые методы/классыSonarQube / CodeClimateМетоды без тела или с пустым телом
Дублирующие библиотекиGradle lint (duplicate classes)Конфликты классов из разных библиотек

Для полноценного аудита запускайте buildHealth (Android) или depcheck (Node.js) раз в спринт. Создайте дашборд в CI, который показывает динамику количества зависимостей по спринтам. Если количество растёт, а функциональность не растёт пропорционально — команда накапливает джанк.

Обратите внимание на duplicate classes — ошибку, когда две библиотеки содержат один и тот же класс. Это не только джанк, но и прямой источник конфликтов сборки. В Gradle такие конфликты разрешаются через force или exclude, но каждое такое разрешение — сигнал, что одна из библиотек лишняя.

Процесс регулярной чистки проекта

Чистка джанка — это не разовая акция, а регулярный процесс. Без регламента джанк возвращается в течение двух-трёх спринтов. Лучшая практика — выделять 10–15 процентов ёмкости каждого спринта на техническую чистку, включая аудит джанка.

Процесс состоит из четырёх шагов. Первый — диагностика: запуск инструментов, получение отчёта, приоритизация. Высокий приоритет — зависимости с известными CVE и дублирующие библиотеки. Средний — мёртвые импорты и закомментированный код. Низкий — избыточные абстракции (требуют ручного анализа).

Второй — чистка: удаление мёртвых зависимостей, замена дублирующих библиотек на одну, удаление закомментированного кода. Каждое изменение делается отдельным коммитом с понятным message: «remove unused dependency: gson (replaced by kotlinx.serialization)», «delete commented code in LoginViewModel».

Третий — верификация: сборка проекта, прогон тестов, проверка UI. Если после удаления зависимости тесты проходят — зависимость действительно была не нужна. Если тесты падают — значит, где-то осталась скрытая ссылка, которую не обнаружил статический анализатор.

Четвёртый — профилактика: обновление чек-листа code review, добавление правила «ни одной новой зависимости без обоснования» в Definition of Done, настройка автоматической проверки в CI. Профилактика — единственный способ не допустить повторного накопления джанка.

Часто задаваемые вопросы

Чем джанк отличается от технического долга?

Технический долг — это осознанное компромиссное решение (быстро, но некачественно), которое планируется исправить. Джанк — это не осознанное решение, а накопленный мусор: лишние зависимости, закомментированный код, пустые абстракции, которые никто не планировал и не хочет поддерживать.

Как часто нужно чистить джанк?

Оптимальный ритм — каждый спринт выделять 10 процентов времени на техническую чистку. Это позволяет держать джанк под контролем, не накапливая критическую массу. Если в проекте джанка много — начните с одного большого спринта чистки, а затем переходите на регулярный ритм.

Как убедить команду удалять джанк?

Измерьте и покажите цифры: замерьте время сборки до и после удаления 3–5 лишних зависимостей. Сокращение на 15–30 секунд за сборку умножается на количество сборок в день и даёт часы сэкономленного времени команды. Цифры убеждают лучше абстрактных призывов к чистоте.

Стоит ли удалять джанк из зависимостей, если проект стабилен?

Да, особенно если у зависимости есть CVE. Даже если проект стабилен, уязвимость в транзитивной зависимости — это риск безопасности. Кроме того, при обновлении SDK или языка старая зависимость может перестать быть совместимой, и её удаление до апгрейда сэкономит часы миграции.

Что делать с TODO в коде?

Каждый TODO без тикета — это джанк. Установите правило: TODO пишется только в формате // TODO(PROJECT-1234): fix с привязкой к задаче в трекере. Регулярно проверяйте TODO и закрывайте те, которые потеряли актуальность. Просроченные TODO удаляйте — если проблема не всплыла за полгода, она не критична.

Итоги

  • Джанк — бесполезный код, неиспользуемые зависимости и избыточные абстракции, увеличивающие проект без пользы.
  • Четыре категории: избыточные зависимости, мёртвый груз, дублирующие библиотеки и овер-инжиниринг.
  • Каждая лишняя зависимость — это рост времени сборки, поверхности атак и когнитивной нагрузки.
  • Инструменты аудита: dependency-analysis (Gradle), depcheck (Node.js), SonarQube, grep для закомментированного кода.
  • Регулярная чистка: 10–15 процентов спринта на техническую работу, аудит зависимостей раз в спринт.
  • Профилактика: code review с чеком на новые зависимости, YAGNI при проектировании, авто-чистка импортов.
  • Правило: ни одной новой зависимости без обоснования, ни одного TODO без тикета, ни строки закомментированного кода в master.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также