Come l'app desktop di WebCatalog usa i cloni APFS per ridurre fino a 8 volte lo spazio su disco occupato dalle app su Mac

L’app desktop di WebCatalog ora usa i cloni APFS su macOS per ridurre drasticamente l’uso dello spazio su disco. Memorizzando una sola volta i dati identici di Electron e Photon, le app aggiuntive occupano in genere solo 1–2 MB di spazio fisico anziché circa 320 MB.

23 settembre 2026

Nguyen Tran · Software Engineer

Come l'app desktop di WebCatalog usa i cloni APFS per ridurre fino a 8 volte lo spazio su disco occupato dalle app su Mac

Ogni app creata con l’app desktop di WebCatalog occupava circa 320 MB di spazio su disco in macOS. Non è insolito per un’app basata su Electron, ma WebCatalog è pensato per chi usa molte app web come app desktop. Installandone dieci, potevano occupare più di 3 GB, anche se gran parte dei dati al loro interno era identica.

Di recente abbiamo cambiato il modo in cui l’app desktop di WebCatalog crea le app su macOS. La prima app ora occupa circa 340 MB di spazio fisico su disco, inclusa una copia dell’engine dell’app preparata e conservata in locale. Da quel momento, ogni app aggiuntiva comporta in genere solo 1–2 MB di spazio fisico in più. Nei nostri test, dieci app sono passate da più di 3 GB a circa 360 MB.

Ci siamo riusciti usando una funzionalità già integrata in macOS: i cloni APFS. La parte interessante non era semplicemente clonare i file, ma far funzionare la clonazione mantenendo ogni app indipendente, correttamente firmata e funzionalmente equivalente a un’app creata con il vecchio processo.

Perché ogni app occupava altri 320 MB

L’app desktop di WebCatalog trasforma i siti web in app desktop autonome. Ogni app creata viene eseguita su Photon, il nostro engine basato su Electron. Su macOS, ciascuna è un normale bundle .app che contiene Electron (Chromium e Node.js), Photon e i file specifici dell’app.

Prendiamo per esempio due app, Slack e Discord. Nomi, icone, identificatori dei bundle e configurazioni sono diversi, ma il grande framework Electron e gran parte di Photon sono identici.

Fino a oggi, ogni app veniva creata come una copia completamente separata.

Slack.app
  Electron
  Photon
  File specifici di Slack

Discord.app
  Electron
  Photon
  File specifici di Discord

Il framework Electron e Photon potevano essere identici byte per byte nelle due app, ma macOS memorizzava comunque un’altra copia fisica per ciascuna. Dieci app significavano quindi circa dieci copie dello stesso bundle applicativo da 320 MB.

Questa architettura aveva però una caratteristica che volevamo preservare: ogni app era completamente indipendente. Eliminandone una non si poteva compromettere un’altra e le app installate non dipendevano dalla presenza dell’app desktop di WebCatalog sul sistema.

Volevamo eliminare la duplicazione superflua sottostante.

APFS offriva già il meccanismo di cui avevamo bisogno

I Mac moderni usano APFS, il file system di Apple. APFS supporta la clonazione, un meccanismo copy-on-write che permette a due file indipendenti di condividere gli stessi dati fisici finché uno dei due non cambia.

Immaginiamo di copiare un file da 300 MB. Con una copia normale, macOS scrive altri 300 MB sul disco, quindi i due file occupano in totale circa 600 MB.

Con un clone APFS, il nuovo file appare e si comporta comunque come un file completo da 300 MB, ma inizialmente fa riferimento agli stessi blocchi fisici dell’originale.

File A ─────┐
            ├── blocchi fisici condivisi
File B ─────┘

Se in seguito una parte del File B cambia, APFS scrive nuovi blocchi solo per i dati modificati. Tutto ciò che rimane identico può continuare a condividere i blocchi originali.

File A ───────── blocchi condivisi

File B ───────── blocchi condivisi
       └──────── blocchi modificati

Dal punto di vista dell’applicazione, il File A e il File B sono file separati. Dal punto di vista dell’SSD, i dati identici devono essere memorizzati una sola volta.

Era quasi esattamente il comportamento di cui avevamo bisogno.

Creare le app da una base comune

L’app desktop di WebCatalog ora prepara una base per ogni combinazione di versioni di Electron e Photon. L’app Photon di base contiene le parti identiche tra le app, inclusi Electron, Photon, la struttura del framework e le firme comuni.

Quando l’app desktop crea un’altra app usando le stesse versioni, non estrae e costruisce più da zero un’altra copia completa. Crea invece un clone APFS dell’app Photon di base e personalizza solo le parti che devono essere diverse.

Tra queste ci sono il nome dell’app, l’icona, l’identificatore del bundle, le impostazioni, i nomi degli eseguibili, l’identificatore della build e altri metadati specifici dell’app.

Poiché gran parte del bundle rimane invariata, APFS continua a condividere i blocchi fisici che contengono Electron e Photon. Solo la quantità relativamente piccola di dati specifici dell’app occupa nuovo spazio.

Perché non condividere semplicemente Electron?

Un approccio più ovvio sarebbe installare Electron una sola volta e fare in modo che ogni app vi faccia riferimento.

Lo abbiamo preso in considerazione, ma cambierebbe radicalmente il modello di affidabilità. Se l’installazione condivisa di Electron scomparisse, tutte le app che ne dipendono potrebbero smettere di funzionare. Un programma di pulizia della cache potrebbe rimuoverla, la disinstallazione dell’app desktop di WebCatalog potrebbe eliminarla e spostare o ripristinare una singola app diventerebbe più complicato.

Sarebbe inoltre necessario tenere traccia delle versioni del runtime da cui dipende ogni app installata, per poter rimuovere in sicurezza le versioni precedenti.

La firma del codice su macOS pone un altro problema. La verifica rigorosa della firma rifiuta i link simbolici che puntano all’esterno del bundle dell’app.

I cloni APFS ci offrono i vantaggi della condivisione senza introdurre questa dipendenza. Le app installate possono condividere blocchi fisici sul disco pur rimanendo bundle applicativi completi e indipendenti.

Eliminare l’app Photon di base non compromette le app create a partire da essa. Eliminare un’app installata non influisce sulle altre. Il file system gestisce la condivisione, mentre l’architettura delle app rimane indipendente.

La firma del codice ha rischiato di annullare il risparmio

Clonare l’app era solo una parte del problema. Le applicazioni macOS devono anche essere firmate.

La nostra vecchia pipeline di creazione firmava nuovamente in profondità ogni bundle applicativo dopo la personalizzazione. Per una copia normale, questo non è un problema. Con un’archiviazione copy-on-write, però, modificare un binario di grandi dimensioni può indurre APFS ad allocare nuovi blocchi fisici.

Durante lo sviluppo abbiamo misurato che firmare nuovamente il framework Electron aggiungeva circa 194 MB di spazio fisico per app. Eravamo riusciti a evitare di copiare Electron durante la creazione dell’app, solo per duplicarne nuovamente gran parte durante la firma.

Dovevamo quindi cambiare anche il processo di firma.

Il grande framework comune viene ora firmato come parte dell’app Photon di base. Quando l’app desktop clona questa base, evitiamo di modificare i grandi binari condivisi e firmiamo nuovamente solo le parti più piccole che devono effettivamente differire tra le app.

Una volta completata l’app, eseguiamo una verifica rigorosa della firma sul bundle finale per assicurarci che tutto rimanga valido.

Questo ci permette di mantenere sia le garanzie offerte dalla firma del codice di macOS sia il risparmio di spazio ottenuto con APFS.

Quando chiedere a Node.js di clonare non produceva un clone

C’era un altro problema inatteso: eseguire la clonazione stessa.

Node.js mette a disposizione opzioni di copia pensate per richiedere il comportamento copy-on-write, tra cui COPYFILE_FICLONE e COPYFILE_FICLONE_FORCE. Sulla carta sembravano esattamente le API di cui avevamo bisogno.

Nei nostri test con Node.js 24, abbiamo copiato la stessa applicazione Electron da 288 MB con diversi metodi e misurato quanto spazio fisico aggiuntivo occupasse ogni operazione:

fs.cpSync                              +288 MB
fs.cpSync + COPYFILE_FICLONE           +288 MB
fs.cpSync + COPYFILE_FICLONE_FORCE     +288 MB
/bin/cp -c -R                          ~0 MB

Entrambe le modalità di clonazione di Node.js producevano comunque una copia fisica completa nel nostro test, e persino la variante FORCE non segnalava alcun errore quando la clonazione prevista non avveniva.

Il comando nativo cp -c di macOS si comportava come previsto, quindi l’app desktop di WebCatalog usa direttamente quel meccanismo.

È stato anche un utile promemoria: le ottimizzazioni del file system vanno verificate misurando il file system stesso. Chiamare un’API che richiede il copy-on-write non significa necessariamente che i file risultanti condividano davvero lo spazio fisico.

Rendere sicuro anche il fallimento dell’ottimizzazione

Risparmiare spazio su disco è un’ottimizzazione. Installare correttamente un’app è una necessità.

Abbiamo progettato la nuova pipeline in modo che un eventuale fallimento della clonazione non impedisca l’installazione dell’app. Se la preparazione dell’app Photon di base non riesce, se la base nella cache è danneggiata, se la clonazione fallisce o se la verifica della firma non va a buon fine, l’app desktop torna al precedente processo di creazione, con estrazione e firma complete.

Nel peggiore dei casi, quindi, lo spazio occupato è lo stesso di prima: l’installazione non fallisce.

Abbiamo dovuto tenere conto anche delle operazioni simultanee. Un’app Photon di base viene prima preparata in una directory temporanea e spostata nella posizione definitiva solo quando è completa. In questo modo, due app create contemporaneamente non possono accedere per errore a una base ancora incompleta.

Anche le basi più vecchie possono essere rimosse in sicurezza. Un clone APFS installato non dipende dalla presenza della base originale. Se la base viene eliminata, il clone conserva i blocchi fisici che utilizza ancora.

Questo funziona su APFS, il file system predefinito di tutti i Mac moderni. Se le tue app si trovano su un disco che non supporta la clonazione, come un’unità esterna HFS+ o exFAT, l’app desktop di WebCatalog ricorre a una copia normale: le app funzionano come prima, ma senza risparmiare spazio. Per ora, su Windows e Linux non cambia nulla.

Dimensione logica e dimensione fisica non sono la stessa cosa

Un effetto collaterale un po’ fuorviante è che il Finder potrebbe continuare a indicare una dimensione di circa 320 MB per ogni app.

Quel numero rappresenta la dimensione logica dell’app. L’app contiene effettivamente circa 320 MB di file e, se questi venissero copiati altrove senza clonazione, sarebbe all’incirca la quantità di dati da scrivere.

A cambiare è la dimensione fisica, ovvero il numero di blocchi distinti che quei file occupano effettivamente sul disco.

Se due app contengono lo stesso framework da 300 MB e APFS permette loro di condividere gli stessi blocchi sottostanti, ciascuna può contenere logicamente 300 MB, mentre la seconda aggiunge pochissimi nuovi dati fisici.

La finestra Ottieni informazioni del Finder e strumenti come du non rendono necessariamente visibile questa condivisione. Il risparmio si nota soprattutto dalla quantità di spazio libero che rimane effettivamente sul disco.

Lo abbiamo verificato con sette app reali: Discord, Facebook, Instagram, Messenger, TikTok e due app personalizzate. Create in questo modo, hanno risparmiato circa 1,9 GB di spazio su disco rispetto al vecchio processo.

Abbiamo anche controllato gli offset fisici sul disco e confermato che le app condividevano a livello di blocchi i dati comuni di Electron e Photon. Un’app creata con il vecchio processo non condivideva nessuno di quei blocchi, fornendoci un utile termine di paragone.

Il risultato

Per chi crea una sola app con l’app desktop di WebCatalog, la differenza è minima. La prima app occupa in realtà un po’ più spazio di prima, perché l’app desktop conserva anche l’app Photon di base usata per creare i cloni successivi.

Da quel momento, il vantaggio cresce rapidamente.

Prima

1 app       ~320 MB
10 app      >3 GB

Con la clonazione APFS:

Dopo

1 app       ~340 MB
10 app      ~360 MB

Dopo la creazione della base iniziale, ogni app aggiuntiva comporta in genere solo 1–2 MB di spazio fisico in più sul disco.

Il punto importante è che abbiamo ottenuto questo risultato senza introdurre una dipendenza da un runtime condiviso. Ogni app rimane una normale applicazione macOS autonoma, mentre APFS memorizza una sola volta i dati identici di Electron e Photon. Con circa dieci app installate, questo può ridurre lo spazio su disco effettivamente occupato di oltre otto volte.

Questa funzionalità è disponibile nell’ultima versione dell’app desktop di WebCatalog su macOS. Non devi attivare nulla: le nuove app la usano automaticamente e quelle che hai già occuperanno meno spazio al prossimo aggiornamento.