Il codice spazzatura (junk code) si riferisce a codice e dipendenze che non apportano beneficio a un progetto ma ne aumentano le dimensioni, il tempo di compilazione e il carico cognitivo sul team. A differenza del codice morto che non viene mai eseguito, lo junk può funzionare ma lo fa in modo inefficiente o ridondante: librerie duplicate, importazioni inutilizzate, blocchi commentati, polyfill obsoleti e astrazioni decorative. Secondo il CodeScene Code Health Report (2025), in media il 15 per cento delle dipendenze nei progetti mobili non viene utilizzato direttamente e trascina solo pacchetti transitivi. Il codice spazzatura è il “peso extra” di un progetto: rende la base di codice più spessa ma non più forte. Audit regolari delle dipendenze e la rimozione di astrazioni ridondanti migliorano direttamente la velocità di compilazione e la qualità del codice.
Punti chiave
Junk (codice spazzatura) è un termine collettivo per codice, configurazioni e dipendenze che esistono in un progetto ma non forniscono valore funzionale. Lo junk non è necessariamente rotto o inutilizzato — il problema è che la sua presenza peggiora le metriche del progetto senza una giustificazione adeguata.
Lo junk si divide in quattro categorie. Prima — dipendenze ridondanti: librerie aggiunte per una singola funzionalità che avrebbe potuto essere implementata con strumenti standard. Seconda — peso morto: blocchi commentati, TODO senza ticket, metodi vuoti e classi stub. Terza — soluzioni duplicate: due librerie che fanno la stessa cosa (ad esempio, Gson e Kotlin Serialization in uno stesso progetto). Quarta — over-engineering: strati architetturali che non vengono utilizzati ma sono mantenuti “per sicurezza.”
Secondo la ricerca di Stripe Engineering Productivity (2025), rimuovere il 10 per cento di junk da un progetto tipico riduce il tempo di compilazione completo in media del 22 per cento. La ragione: ogni dipendenza extra aumenta il grafo di compilazione, ogni astrazione vuota richiede tempo per essere compresa, ogni blocco commentato distrae l’attenzione.
La principale difficoltà nella lotta contro lo junk è l’assenza di conseguenze immediate. Un progetto con codice spazzatura compila e funziona. I problemi si accumulano gradualmente: la compilazione rallenta, il numero di dipendenze transitive cresce, e dopo un anno aggiungere una nuova funzionalità richiede il doppio del tempo necessario.
Dipendenze spazzatura sono librerie e pacchetti aggiunti a un progetto che non vengono utilizzati direttamente nel codice, o sono utilizzati solo per una singola funzionalità che sarebbe più semplice implementare con API standard.
Esempi tipici: una libreria per l’elaborazione JSON quando il progetto utilizza già Kotlin Serialization (due parser sono junk); la libreria Apache Commons Lang per una singola chiamata StringUtils.isEmpty che potrebbe essere sostituita dall’estensione Kotlin isNullOrBlank; una libreria DI utilizzata in un modulo su dieci mentre gli altri ricevono dipendenze manualmente tramite costruttore.
Ogni dipendenza extra non è solo codice aggiuntivo nel binario. Aumenta la superficie d’attacco per le vulnerabilità: secondo GitHub Advisory Database (2025), il 40 per cento dei CVE critici nei progetti mobili proviene da dipendenze transitive che gli sviluppatori non controllano. Meno dipendenze ci sono, minore è la superficie d’attacco.
// 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
Per iOS, utilizzare il comando swift package show-dependencies, che mostra l’albero completo delle dipendenze. Lo strumento Xcode Build Timeline mostra quanto tempo di compilazione aggiunge ogni libreria. Se una libreria occupa il 30 per cento del tempo di compilazione ma viene utilizzata su un solo schermo, è candidata alla rimozione o sostituzione.
Per Node.js (React Native), utilizzare depcheck — un utilità che trova dipendenze inutilizzate in package.json, e npm-check, che mostra inoltre le versioni obsolete. Introdurre una regola: ogni nuova dipendenza deve superare una revisione del codice con una giustificazione del “perché non è possibile utilizzare strumenti standard.”
Importazioni morte sono il tipo più comune di junk. Non influiscono sul runtime ma aumentano il tempo di compilazione: il compilatore elabora ogni importazione, anche quelle inutilizzate. Nei progetti grandi, rimuovere le importazioni inutilizzate riduce il tempo di compilazione del 5–10 per cento.
Gli IDE moderni evidenziano automaticamente le importazioni inutilizzate in grigio. Impostare la pulizia automatica al salvataggio: in IntelliJ IDEA — Optimize Imports on the fly, in Xcode — Editor > Remove Unused Imports. Aggiungere un controllo in CI: il linter deve bloccare i commit con importazioni inutilizzate.
Codice commentato è un altro tipo di junk. Gli sviluppatori commentano blocchi per “non perdere” funzionalità durante il refactoring. Tuttavia, git memorizza l’intera cronologia delle modifiche: qualsiasi codice rimosso può essere ripristinato con un singolo comando git revert o git log -S
La regola: non c’è codice commentato nel repository. Se il codice non è necessario, eliminarlo definitivamente. Se il codice è necessario ma temporaneamente disabilitato, utilizzare un feature toggle con un ticket e una data di scadenza. Commenti come // TODO: remove after migration — non lasciarli senza scadenza. Impostare una data e ricordarsi con un calendario.
Over-engineering è la creazione di strati architetturali che non risolvono problemi attuali ma richiedono manutenzione. Questo è uno dei tipi di junk più difficili perché formalmente il codice è “corretto”: segue SOLID, è coperto da test ed è conforme all’architettura. Il problema è che non è necessario.
Un esempio classico è una classe astratta UseCase con un singolo metodo invoke che chiama semplicemente un repository. Se il UseCase non aggiunge logica (caching, retry, trasformazione) e passa solo la chiamata, è un’entità extra. Aumenta la navigazione nel progetto: uno sviluppatore apre il UseCase, vede invoke → repository e lo chiude. Tempo sprecato, beneficio zero.
Un altro esempio è la parametrizzazione eccessiva. Un’interfaccia generica con sei parametri di tipo utilizzata in un unico punto. Ogni parametro di tipo aggiunge carico cognitivo: durante la lettura del codice, bisogna tenere a mente sei tipi mentre solo due sono effettivamente utilizzati. Se un’astrazione non viene riutilizzata, è ridondante.
Il criterio di taglio: se un’astrazione non viene riutilizzata in tre contesti diversi, rimuoverla. Un’astrazione è giustificata quando risolve effettivamente un problema di duplicazione, non quando prevede scenari ipotetici futuri. YAGNI (You Ain’t Gonna Need It) è il miglior principio per prevenire l’over-engineering.
L’audit dello junk richiede una combinazione di analisi statica, analisi delle dipendenze e revisione manuale. È impossibile automatizzare completamente la rilevazione di astrazioni ridondanti, ma lo junk tecnico (importazioni morte, librerie inutilizzate, codice commentato) può essere trovato con strumenti.
| Categoria | Strumento | Cosa verifica |
|---|---|---|
| Dipendenze inutilizzate | dependency-analysis (Gradle) | Librerie non utilizzate nel codice |
| Dipendenze inutilizzate | depcheck (Node.js) | Pacchetti da package.json senza importazioni |
| Dipendenze inutilizzate | swift package --show-dependencies | Albero delle dipendenze SwiftPM |
| Importazioni morte | IDE (Optimize Imports) | Istruzioni import inutilizzate |
| Codice commentato | grep -r “//” / rg “^\s*//” | Blocchi di commenti con codice |
| Metodi/classi vuoti | SonarQube / CodeClimate | Metodi senza corpo o con corpo vuoto |
| Librerie duplicate | Gradle lint (duplicate classes) | Conflitti di classi da librerie diverse |
Per un audit completo, eseguire buildHealth (Android) o depcheck (Node.js) una volta per sprint. Creare una dashboard in CI che mostri l’andamento del numero di dipendenze attraverso gli sprint. Se il numero aumenta ma la funzionalità non aumenta proporzionalmente, il team sta accumulando junk.
Prestare attenzione alle classi duplicate — un errore che si verifica quando due librerie contengono la stessa classe. Questo non è solo junk ma anche una fonte diretta di conflitti di compilazione. In Gradle, questi conflitti vengono risolti tramite force o exclude, ma ogni risoluzione è un segnale che una delle librerie è superflua.
La pulizia dello junk non è un’azione una tantum ma un processo regolare. Senza una procedura, lo junk ritorna entro due o tre sprint. La migliore pratica è allocare il 10–15 per cento della capacità di ogni sprint alla pulizia tecnica, incluso l’audit dello junk.
Il processo si compone di quattro fasi. Prima — diagnostica: eseguire gli strumenti, ottenere un rapporto, prioritizzare. Alta priorità: dipendenze con CVE noti e librerie duplicate. Media priorità: importazioni morte e codice commentato. Bassa priorità: astrazioni ridondanti (richiedono analisi manuale).
Seconda — pulizia: rimuovere dipendenze morte, sostituire librerie duplicate con una, eliminare codice commentato. Ogni modifica deve essere un commit separato con un messaggio chiaro: “remove unused dependency: gson (replaced by kotlinx.serialization)”, “delete commented code in LoginViewModel.”
Terza — verifica: compilare il progetto, eseguire i test, controllare l’interfaccia. Se i test passano dopo la rimozione di una dipendenza, la dipendenza era effettivamente superflua. Se i test falliscono, c’è un riferimento nascosto che l’analizzatore statico non ha rilevato.
Quarta — prevenzione: aggiornare la checklist di code review, aggiungere una regola “nessuna nuova dipendenza senza giustificazione” alla Definition of Done, impostare controlli automatici in CI. La prevenzione è l’unico modo per evitare un nuovo accumulo di junk.
Domande frequenti
Il debito tecnico è un compromesso consapevole (veloce ma di bassa qualità) che si pianifica di correggere. Lo junk non è una decisione consapevole ma spazzatura accumulata: dipendenze extra, codice commentato, astrazioni vuote che nessuno ha pianificato o vuole mantenere.
Il ritmo ottimale è allocare il 10 per cento di ogni sprint alla pulizia tecnica. Questo mantiene lo junk sotto controllo senza accumulare massa critica. Se un progetto ha molto junk, iniziare con un grande sprint di pulizia e poi passare a un ritmo regolare.
Misurare e mostrare i numeri: misurare il tempo di compilazione prima e dopo la rimozione di 3–5 dipendenze extra. Una riduzione di 15–30 secondi per compilazione moltiplicata per il numero di compilazioni al giorno dà ore di tempo risparmiato per il team. I numeri convincono meglio di appelli astratti alla pulizia.
Sì, specialmente se la dipendenza ha un CVE. Anche se il progetto è stabile, una vulnerabilità in una dipendenza transitiva è un rischio per la sicurezza. Inoltre, durante l’aggiornamento di un SDK o linguaggio, una vecchia dipendenza potrebbe diventare incompatibile, e la sua rimozione prima dell’aggiornamento farà risparmiare ore di migrazione.
Ogni TODO senza ticket è junk. Stabilire una regola: TODO viene scritto solo nel formato // TODO(PROJECT-1234): fix collegato a un’attività nel tracker. Controllare regolarmente i TODO e chiudere quelli che hanno perso rilevanza. Rimuovere i TODO scaduti — se il problema non è emerso in sei mesi, non è critico.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche