Minificare JSON

Incolla del JSON e ottieni gli stessi dati senza un solo spazio superfluo, insieme a quanto ha davvero risparmiato — in byte e non in caratteri, perché con accenti ed emoji sono due numeri diversi. Il documento viene analizzato e riscritto, non modificato con un cerca-e-sostituisci: è per questo che gli spazi dentro una stringa sopravvivono.

Risultato

La risposta compare qui mentre scrivi.

  • Dove gira

    Non viene caricato nulla, perché non c’è nessun file: il calcolo avviene in questa pagina.

  • Nessuna coda, nessun account

    Risponde alla velocità della tua macchina e non chiede mai chi sei.

  • Tutte le volte che vuoi

    Non si conta né si limita nulla: rispondere di nuovo non ci costa niente.

Come funziona

  1. Incolla il JSON.
  2. Decidi se ordinare le chiavi in ordine alfabetico, utile se devi confrontare due documenti.
  3. Copia la riga. Non è stato caricato niente.

Analizzato, non tagliato

Il documento viene letto da un parser vero e riscritto senza spazi superflui. La differenza rispetto a un cerca-e-sostituisci si vede sul primo documento che contiene uno spazio dentro una stringa: `{"nome": "Maria Rossi"}` deve restare `Maria Rossi` e non diventare `MariaRossi`.

Ne segue anche che un documento rotto non produce niente. Sembra meno comodo di un risultato parziale e non lo è: una riga sola di JSON non valido è molto più difficile da riparare di un documento formattato non valido, perché non ci sono più righe da indicare. Chi ha un documento che non passa ha bisogno della pagina di validazione, non di questa.

Il risparmio si misura in byte

Il risparmio dichiarato qui è in byte, misurati sulla codifica UTF-8, e non nel numero di caratteri. Sono due cose diverse appena il documento contiene qualcosa di italiano: `à`, `è` e `ù` valgono due byte ciascuna, il simbolo dell’euro tre, un emoji quattro.

La differenza conta perché tutto quello che si misura davvero è in byte: il limite di dimensione di una richiesta, la quota di una variabile di configurazione, la lunghezza massima di un campo. Uno strumento che dichiari un risparmio in caratteri dà un numero che non corrisponde a nessuna soglia reale, e su un documento con molti accenti sbaglia di parecchio.

Cosa aggiunge minificare quando c’è già la compressione

Molto meno di quanto suggerisca la differenza in byte. Gli spazi e i rientri sono ripetizioni regolari, cioè esattamente ciò che Gzip e Brotli eliminano meglio: un documento formattato e lo stesso documento minificato, una volta compressi, differiscono spesso di pochi punti percentuali.

Resta un guadagno, e in tre casi conta davvero: quando il documento non passa da un canale compresso, come una variabile d’ambiente o un campo di database; quando viene contato a byte, come in una quota o in un limite di dimensione della richiesta; e quando ne vengono conservati milioni, dove qualche punto percentuale diventa spazio su disco vero.

A cosa serve ordinare le chiavi

A confrontare. Due sistemi che producono gli stessi dati raramente li scrivono nello stesso ordine, quindi un confronto testuale segnala differenze che non esistono. Ordinare le chiavi in entrambi i documenti toglie di mezzo quel rumore e lascia solo le differenze vere.

Gli array restano intatti, perché lì l’ordine è il dato. Una lista di passaggi, una cronologia di eventi, una classifica: riordinarli produrrebbe un documento ancora valido e con un altro significato, che è la peggior categoria di trasformazione, perché niente segnala che è successo.

Ordinare non è canonicalizzare

Se ti serve una forma canonica per firmare un documento, ordinare le chiavi non basta. Una canonicalizzazione vera deve fissare anche come si scrivono i numeri, come si normalizzano le stringhe Unicode e come si trattano i valori duplicati: sono le regole di JCS, la RFC 8785, e sono più severe di quanto sembri.

La conseguenza pratica è netta: due documenti minificati e ordinati possono ancora avere hash diversi pur contenendo gli stessi dati, per esempio se uno scrive `1.0` e l’altro `1`. Se la firma è il punto, la libreria da usare è una che implementi JCS, e questa pagina serve a leggere e a spedire, non a firmare.

Dove i numeri perdono colpi

Anche qui vale il limite di ogni parser JSON basato su JavaScript: gli interi restano esatti fino a 9.007.199.254.740.991, e oltre quella soglia vengono arrotondati. Minificare non aggrava il problema, ma lo attraversa, perché il documento viene analizzato e riscritto.

Merita una parola in più proprio qui, perché il JSON minificato è quello che parte verso un altro sistema. Un identificatore modificato dentro un documento formattato lo si nota rileggendolo; dentro una riga di quattromila caratteri infilata in una variabile di configurazione non lo nota nessuno finché qualcosa non smette di trovare un record.

Una riga sola non è roba da repository

Un file di configurazione minificato e versionato produce un diff che dice «riga 1 modificata» a ogni cambiamento, il che rende inutile metà del valore del controllo di versione: non si vede più cosa è cambiato, non si può commentare una riga in una revisione e un conflitto di merge diventa manuale.

La regola pratica è tenere il documento formattato dove lo leggono le persone e minificarlo nel passo che lo spedisce. È la stessa distinzione che vale per il codice sorgente, e la ragione per cui questa pagina e quella di formattazione sono due strumenti separati invece di un interruttore.

L’a capo finale

Il risultato qui non ha un ritorno a capo in fondo, perché è pensato per essere copiato dentro qualcosa: un campo, una variabile, il corpo di una richiesta. Un carattere in più lì può contare, per esempio quando quel valore viene poi passato per una funzione di hash.

Se invece lo salvi come file, aggiungerne uno è la scelta giusta: gli strumenti a riga di comando presuppongono che un file di testo finisca con un a capo, e senza di quello Git segnala «no newline at end of file» a ogni diff. Sono due destinazioni diverse con due convenzioni diverse, e vale la pena sapere quale delle due si sta usando.

Il documento non viene spedito per essere accorciato

Quello che si minifica è, quasi sempre, un documento reale che sta per andare da qualche parte: una configurazione con dentro delle credenziali, un payload con dei dati di clienti, una risposta da incastrare in un campo. Mandarlo a un servizio remoto per fargli togliere degli spazi è un pessimo scambio.

Qui il parser è quello del browser e il conto dura pochi millisecondi, quindi non c’è nessun trasferimento da giustificare nel senso del GDPR e nessun log altrui in cui il documento possa restare. È lo stesso motivo per cui non c’è nessuna cronologia dei documenti recenti.

Minificare JSON: domande frequenti

Gli spazi dentro le mie stringhe vengono conservati?

Sì, sempre. Il documento viene analizzato e riscritto, non modificato a livello di testo, quindi la minificazione tocca soltanto lo spazio fra i valori. `"Maria Rossi"` resta `"Maria Rossi"`: è la differenza fra un parser e un cerca-e-sostituisci, e si vede sul primo documento reale.

Ne vale la pena se la mia API usa già la compressione?

Poco: rientri e spazi sono ripetizioni regolari, cioè quello che Gzip e Brotli comprimono meglio, quindi la differenza dopo la compressione è spesso di pochi punti percentuali. Conta dove il canale non è compresso — una variabile d’ambiente, un campo di database — e dove qualcosa conta i byte.

Perché il mio identificatore lungo cambia?

Perché supera 9.007.199.254.740.991 e ogni parser JSON basato su JavaScript lo arrotonda. Vale per qualunque strumento, non solo per questo. Qui merita attenzione in più, perché una riga minificata parte verso un altro sistema e nessuno la rilegge: la soluzione è mandare quegli identificatori come stringhe.

Perché il mio documento con i commenti viene rifiutato?

Perché JSON non ha commenti, e nemmeno la virgola dopo l’ultimo elemento o le virgolette singole. Quello che le ammette è JSON5, oppure JSONC, il formato di tsconfig.json e delle impostazioni di parecchi editor. Si assomigliano e non sono la stessa cosa.

Il mio JSON esce dalla mia macchina?

No. Viene analizzato e riscritto nella scheda con il parser del browser, e nessuna richiesta porta con sé il testo. Conta, perché quello che si minifica è spesso una configurazione con dentro credenziali o un payload con dati di clienti.

Altri strumenti