Sådan bruger WebCatalogs desktopapp APFS-kloner til at reducere Mac-apps diskforbrug med op til otte gange

WebCatalogs desktopapp bruger nu APFS-kloner på macOS for at reducere diskforbruget markant. Ved kun at gemme identiske Electron- og Photon-data én gang optager ekstra apps typisk kun 1–2 MB ekstra fysisk lagerplads i stedet for omkring 320 MB.

23. september 2026

Nguyen Tran · Software Engineer

Sådan bruger WebCatalogs desktopapp APFS-kloner til at reducere Mac-apps diskforbrug med op til otte gange

Hver app, du oprettede med WebCatalogs desktopapp, brugte tidligere omkring 320 MB diskplads på macOS. Det er ikke usædvanligt for en Electron-baseret app, men WebCatalog er designet til folk, der bruger mange webapps som desktopapps. Installerede du ti af dem, kunne de bruge mere end 3 GB, selvom det meste af indholdet i de pågældende apps var præcis det samme.

Vi har for nylig ændret den måde, WebCatalogs desktopapp bygger apps på macOS. Den første app bruger nu omkring 340 MB fysisk diskplads, inklusive en klargjort kopi af appmotoren, som gemmes lokalt. Derefter tilføjer hver ekstra app typisk kun 1–2 MB reelt diskforbrug. I vores test gik ti apps fra at bruge mere end 3 GB til omkring 360 MB.

Det har vi gjort med en funktion, der allerede er indbygget i macOS: APFS-kloner. Det interessante var ikke blot at klone filer. Det var at få kloning til at fungere, samtidig med at hver app forblev uafhængig, korrekt kodesigneret og funktionelt tilsvarende en app bygget med den gamle proces.

Hvorfor hver app brugte yderligere 320 MB

WebCatalogs desktopapp omdanner websites til selvstændige desktopapps. Hver app, du opretter, kører på Photon, vores appmotor bygget på Electron. På macOS er hver af dem en almindelig .app-pakke, der indeholder Electron (Chromium og Node.js), Photon og filerne til den pågældende app.

Tag for eksempel to apps, Slack og Discord. Deres navne, ikoner, pakkeidentifikatorer og konfiguration er forskellige, men det store Electron-framework og det meste af Photon er identisk.

Indtil nu blev hver app bygget som en helt separat kopi.

Slack.app
  Electron
  Photon
  Slack-specifikke filer

Discord.app
  Electron
  Photon
  Discord-specifikke filer

Electron-frameworket og Photon kunne være identiske byte for byte i begge apps, men macOS lagrede alligevel endnu en fysisk kopi for hver app. Ti apps betød derfor omtrent ti kopier af næsten den samme programpakke på 320 MB.

Den arkitektur havde dog én egenskab, vi gerne ville bevare: Hver app var fuldstændig uafhængig. Sletning af én app kunne ikke påvirke en anden, og installerede apps var ikke afhængige af, at WebCatalogs desktopapp fortsat fandtes på systemet.

Det, vi ville fjerne, var den unødvendige duplikering nedenunder.

APFS havde allerede den mekanisme, vi havde brug for

Moderne Mac-computere bruger Apples APFS-filsystem. APFS understøtter kloning, en copy-on-write-mekanisme, som lader to uafhængige filer dele de samme fysiske data, indtil en af dem ændres.

Forestil dig at kopiere en fil på 300 MB. Ved en almindelig kopiering skriver macOS yderligere 300 MB til disken, så de to filer samlet bruger omkring 600 MB.

Med en APFS-klon ser den nye fil stadig ud og fungerer som en komplet fil på 300 MB, men i første omgang peger den på de samme fysiske blokke som originalen.

Fil A ─────┐
           ├── delte fysiske blokke
Fil B ─────┘

Hvis en del af fil B senere ændres, skriver APFS kun nye blokke til de ændrede data. Alt, der forbliver identisk, kan fortsat dele de oprindelige blokke.

Fil A ───────── delte blokke

Fil B ───────── delte blokke
      └──────── ændrede blokke

Set fra appens side er fil A og fil B separate filer. Set fra SSD'ens side skal identiske data kun lagres én gang.

Det er næsten præcis den funktionalitet, vi havde brug for.

At bygge apps ud fra en fælles base

WebCatalogs desktopapp klargør nu en base for hver kombination af Electron- og Photon-versioner. Photon-basisappen indeholder de dele, der er identiske på tværs af apps, herunder Electron, Photon, frameworkstrukturen og de fælles signaturer.

Når desktopappen opretter endnu en app med de samme versioner, pakker og bygger den ikke længere en helt ny kopi fra bunden. I stedet opretter den en APFS-klon af Photon-basisappen og tilpasser kun de dele, der skal være forskellige.

Det omfatter appens navn, ikon, pakkeidentifikator, indstillinger, navne på eksekverbare filer, build-identifikator og andre appspecifikke metadata.

Fordi det meste af pakken forbliver uændret, fortsætter APFS med at dele de fysiske blokke, der indeholder Electron og Photon. Kun den forholdsvis lille mængde appspecifikke data optager ny plads.

Hvorfor ikke bare dele Electron?

En mere oplagt tilgang ville være at installere Electron én gang og lade alle apps henvise til den.

Det overvejede vi, men det ville grundlæggende ændre pålidelighedsmodellen. Hvis den delte Electron-installation forsvandt, kunne alle apps, der var afhængige af den, holde op med at fungere. Et oprydningsværktøj kunne fjerne den, afinstallation af WebCatalogs desktopapp kunne fjerne den, og det ville blive mere kompliceret at flytte eller gendanne en enkelt app.

Det ville også kræve, at vi holdt styr på, hvilke installerede apps der afhænger af hvilke runtime-versioner, så gamle versioner kunne ryddes sikkert op.

Kodesignering på macOS skaber endnu et problem. Streng signaturkontrol afviser symbolske links, der peger uden for app-pakken.

APFS-kloner giver os fordelene ved deling uden at indføre den afhængighed. Installerede apps kan dele fysiske diskblokke og samtidig forblive komplette, uafhængige programpakker.

Sletning af Photon-basisappen ødelægger ikke de apps, der er oprettet ud fra den. Sletning af én installeret app påvirker ikke en anden. Filsystemet håndterer delingen, mens apparkitekturen forbliver uafhængig.

Kodesignering var tæt på at fjerne besparelsen

At klone appen var kun en del af udfordringen. macOS-apps skal også kodesigneres.

Vores gamle byggeproces gensignerede hele hver programpakke efter tilpasningen. Ved en almindelig kopi er det uproblematisk. Med copy-on-write-lagring kan ændring af en stor binær fil imidlertid få APFS til at allokere nye fysiske blokke til den.

Under udviklingen målte vi, at gensignering af Electron-frameworket tilføjede omkring 194 MB fysisk lagerplads pr. app. Vi havde undgået at kopiere Electron, da appen blev oprettet, blot for at duplikere en stor del af det igen under signeringen.

Derfor måtte signeringsprocessen også ændres.

Det store fælles framework signeres nu som en del af Photon-basisappen. Når desktopappen kloner denne base, undgår vi at ændre de store, delte binære filer og gensignerer kun de mindre dele, der faktisk skal være forskellige fra app til app.

Når appen er færdig, udfører vi en streng signaturkontrol af den færdige pakke for at sikre, at alt stadig er gyldigt.

På den måde bevarer vi både garantierne fra macOS' kodesignering og pladsbesparelsen fra APFS.

Da en anmodning til Node.js om at klone ikke faktisk klonede

Der var endnu et uventet problem: selve kloningen.

Node.js tilbyder kopieringsflag, der er beregnet til at anmode om copy-on-write-funktionalitet, herunder COPYFILE_FICLONE og COPYFILE_FICLONE_FORCE. På papiret lød de som præcis de API'er, vi havde brug for.

I vores test med Node.js 24 kopierede vi den samme Electron-app på 288 MB med flere metoder og målte, hvor meget ekstra fysisk diskplads hver handling brugte:

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

Begge kloningstilstande i Node.js lavede stadig en fuld fysisk kopi i vores test, og selv FORCE-varianten meldte ikke fejl, da den forventede kloning ikke fandt sted.

Den indbyggede macOS-kommando cp -c fungerede som forventet, så WebCatalogs desktopapp bruger den mekanisme direkte.

Det var også en nyttig påmindelse om, at filsystemoptimeringer bør verificeres ved at måle på selve filsystemet. At kalde et API, som anmoder om copy-on-write, betyder ikke nødvendigvis, at de resulterende filer faktisk deler fysisk lagerplads.

At gøre optimeringen sikker, også når den fejler

At spare diskplads er en optimering. At installere en app er en nødvendighed.

Vi har designet den nye proces, så kloning kan fejle, uden at appinstallationen går i stykker. Hvis klargøringen af Photon-basisappen fejler, hvis den cachelagrede base er beskadiget, hvis kloningen fejler, eller hvis signaturkontrollen ikke består, falder desktopappen tilbage til den tidligere byggeproces med fuld udpakning og fuld signering.

Det værste udfald er derfor det samme diskforbrug som før, ikke en mislykket installation.

Vi var også nødt til at tage højde for samtidige processer. En Photon-basisapp klargøres først i en midlertidig mappe og flyttes først til sin endelige placering, når den er færdig. På den måde kan to appbygninger, der foregår samtidig, ikke ved et uheld støde på en halvfærdig base.

Ældre baser kan også fjernes uden problemer. En installeret APFS-klon er ikke afhængig af, at den oprindelige base fortsat findes. Hvis basen slettes, beholder klonen de fysiske blokke, den stadig bruger.

Dette fungerer på APFS, standardfilsystemet på alle moderne Mac-computere. Hvis dine apps ligger på en disk, der ikke kan klone, for eksempel et eksternt HFS+- eller exFAT-drev, falder WebCatalogs desktopapp tilbage til almindelig kopiering. Så fungerer appene som før, men sparer ikke plads. Windows og Linux er indtil videre uændrede.

Logisk størrelse og fysisk størrelse er ikke det samme

En lidt forvirrende bivirkning er, at Finder stadig kan vise hver app som værende omkring 320 MB.

Det tal angiver appens logiske størrelse. Appen indeholder faktisk filer svarende til omtrent 320 MB, og hvis filerne blev kopieret et sted hen uden kloning, er det omtrent så mange data, der skulle skrives.

Det, der har ændret sig, er den fysiske størrelse, altså hvor mange unikke blokke filerne faktisk optager på disken.

Hvis to apps indeholder det samme framework på 300 MB, og APFS lader dem dele de samme underliggende blokke, kan hver app logisk indeholde 300 MB, mens den anden næsten ikke tilføjer nogen nye fysiske data.

Finders Vis info-visning og værktøjer som du viser ikke nødvendigvis denne deling. Besparelsen ses tydeligst på, hvor meget ledig plads der faktisk er tilbage på disken.

Vi bekræftede det med syv rigtige apps: Discord, Facebook, Instagram, Messenger, TikTok og to brugerdefinerede apps. Bygget på denne måde sparede de omkring 1,9 GB diskplads sammenlignet med den gamle byggeproces.

Vi kontrollerede også de underliggende fysiske diskplaceringer og bekræftede, at appene delte deres fælles Electron- og Photon-data på blokniveau. En app, der var oprettet med den gamle byggeproces, delte ingen af disse blokke, hvilket gav os et nyttigt sammenligningsgrundlag.

Resultatet

For en person, der kun opretter én app med WebCatalogs desktopapp, er forskellen lille. Den første app bruger faktisk lidt mere diskplads end før, fordi desktopappen også gemmer den Photon-basisapp, der bruges til at oprette efterfølgende kloner.

Derefter vokser fordelen hurtigt.

Før

1 app       ~320 MB
10 apps     >3 GB

Med APFS-kloning:

Efter

1 app       ~340 MB
10 apps     ~360 MB

Når den første base er oprettet, tilføjer hver ekstra app typisk kun 1–2 MB fysisk diskforbrug.

Det vigtigste er, at vi har opnået dette uden at indføre en afhængighed af et delt runtime-miljø. Hver app forbliver en almindelig, selvstændig macOS-app, mens APFS kun lagrer de identiske Electron- og Photon-data én gang. Med omkring ti installerede apps kan det reducere det faktiske diskforbrug til under en ottendedel.

Dette er tilgængeligt i den nyeste version af WebCatalogs desktopapp til macOS. Du behøver ikke at slå noget til: Nye apps bruger det automatisk, og de apps, du allerede har, fylder mindre, næste gang de opdateres.