Hoe de WebCatalog-desktopapp met APFS-klonen het schijfgebruik van Mac-apps tot acht keer vermindert

De desktopapp van WebCatalog gebruikt nu APFS-klonen op macOS om het schijfgebruik drastisch te verminderen. Doordat identieke Electron- en Photon-gegevens maar één keer worden opgeslagen, nemen extra apps doorgaans slechts 1 à 2 MB aan fysieke opslagruimte in beslag, in plaats van ongeveer 320 MB.

23 september 2026

Nguyen Tran · Software Engineer

Hoe de WebCatalog-desktopapp met APFS-klonen het schijfgebruik van Mac-apps tot acht keer vermindert

Elke app die je met de WebCatalog-desktopapp maakte, nam op macOS voorheen ongeveer 320 MB schijfruimte in beslag. Dat is niet ongebruikelijk voor een app op basis van Electron, maar WebCatalog is bedoeld voor mensen die veel webapps als desktopapps gebruiken. Installeerde je er tien, dan konden ze samen meer dan 3 GB innemen, hoewel de meeste gegevens in die apps precies hetzelfde waren.

We hebben onlangs veranderd hoe de WebCatalog-desktopapp apps bouwt op macOS. De eerste app gebruikt nu ongeveer 340 MB fysieke schijfruimte, inclusief een lokaal bewaarde, voorbereide kopie van de app-engine. Daarna voegt elke extra app doorgaans slechts 1–2 MB aan daadwerkelijk schijfgebruik toe. In onze tests daalde het schijfgebruik van tien apps van meer dan 3 GB naar ongeveer 360 MB.

Daarvoor gebruiken we een functie die al in macOS is ingebouwd: APFS-klonen. De uitdaging was niet alleen om bestanden te klonen. We moesten ervoor zorgen dat dit werkte terwijl elke app onafhankelijk bleef, correct digitaal ondertekend was en functioneel gelijkwaardig was aan een app die met het oude proces was gebouwd.

Waarom elke app nog eens 320 MB gebruikte

De WebCatalog-desktopapp zet websites om in zelfstandige desktopapps. Elke app die je maakt, draait op Photon, onze app-engine op basis van Electron. Op macOS is elke app een normale .app-bundel met Electron (Chromium en Node.js), Photon en de bestanden voor die specifieke app.

Neem bijvoorbeeld twee apps: Slack en Discord. Hun namen, pictogrammen, bundel-ID's en configuraties verschillen, maar het grote Electron-framework en het grootste deel van Photon zijn identiek.

Tot nu toe werd elke app als een volledig afzonderlijke kopie gebouwd.

Slack.app
  Electron
  Photon
  Slack-specifieke bestanden

Discord.app
  Electron
  Photon
  Discord-specifieke bestanden

Het Electron-framework en Photon konden in beide apps byte voor byte identiek zijn, maar macOS sloeg voor elke app toch een nieuwe fysieke kopie op. Tien apps betekenden dus ongeveer tien kopieën van vrijwel dezelfde app-bundel van 320 MB.

Die opzet had wel een eigenschap die we wilden behouden: elke app was volledig onafhankelijk. Het verwijderen van de ene app kon geen gevolgen hebben voor een andere, en geïnstalleerde apps waren er niet van afhankelijk dat de WebCatalog-desktopapp op het systeem bleef staan.

Wat we wilden wegnemen, was de onnodige duplicatie daaronder.

APFS had al precies de basisfunctie die we nodig hadden

Moderne Macs gebruiken Apples APFS-bestandssysteem. APFS ondersteunt klonen: een copy-on-write-mechanisme waarmee twee onafhankelijke bestanden dezelfde fysieke gegevens kunnen delen totdat een van beide verandert.

Stel dat je een bestand van 300 MB kopieert. Bij een gewone kopie schrijft macOS nog eens 300 MB naar de schijf, zodat de twee bestanden samen ongeveer 600 MB innemen.

Bij een APFS-kloon ziet het nieuwe bestand eruit als een volledig bestand van 300 MB en gedraagt het zich ook zo, maar aanvankelijk verwijst het naar dezelfde fysieke blokken als het origineel.

Bestand A ─────┐
               ├── gedeelde fysieke blokken
Bestand B ─────┘

Als later een deel van bestand B verandert, schrijft APFS alleen voor de gewijzigde gegevens nieuwe blokken weg. Alles wat identiek blijft, kan de oorspronkelijke blokken blijven delen.

Bestand A ───────── gedeelde blokken

Bestand B ───────── gedeelde blokken
          └──────── gewijzigde blokken

Voor de app zijn bestand A en bestand B afzonderlijke bestanden. Voor de SSD hoeven identieke gegevens maar één keer te worden opgeslagen.

Dat is vrijwel precies wat we nodig hadden.

Apps bouwen vanuit een gemeenschappelijke basis

De WebCatalog-desktopapp maakt nu een basis voor elke combinatie van Electron- en Photon-versies. De Photon-basisapp bevat de onderdelen die voor alle apps identiek zijn, waaronder Electron, Photon, de frameworkstructuur en de gemeenschappelijke digitale handtekeningen.

Wanneer de desktopapp een andere app met dezelfde versies maakt, pakt ze niet langer een nieuwe volledige kopie uit om die helemaal opnieuw op te bouwen. In plaats daarvan maakt ze een APFS-kloon van de Photon-basisapp en past ze alleen de onderdelen aan die moeten verschillen.

Daaronder vallen de appnaam, het pictogram, de bundel-ID, instellingen, namen van uitvoerbare bestanden, de build-ID en andere app-specifieke metadata.

Omdat het grootste deel van de bundel ongewijzigd blijft, kan APFS de fysieke blokken met Electron en Photon blijven delen. Alleen de relatief kleine hoeveelheid app-specifieke gegevens neemt nieuwe ruimte in beslag.

Waarom niet gewoon Electron delen?

Een meer voor de hand liggende aanpak zou zijn om Electron één keer te installeren en elke app ernaar te laten verwijzen.

We hebben dat overwogen, maar het zou de betrouwbaarheid fundamenteel veranderen. Als de gedeelde Electron-installatie verdween, zouden alle apps die ervan afhankelijk zijn kunnen ophouden te werken. Een opschoonprogramma zou de installatie kunnen verwijderen, het verwijderen van de WebCatalog-desktopapp zou haar kunnen weghalen, en het verplaatsen of herstellen van een afzonderlijke app zou ingewikkelder worden.

Ook zouden we moeten bijhouden welke geïnstalleerde apps afhankelijk zijn van welke runtimeversies, zodat oude versies veilig kunnen worden opgeruimd.

De digitale ondertekening van apps op macOS levert nog een probleem op. Strikte handtekeningverificatie wijst symbolische koppelingen af die naar buiten de app-bundel verwijzen.

Met APFS-klonen krijgen we de voordelen van gedeelde opslag zonder die afhankelijkheid te introduceren. Geïnstalleerde apps kunnen fysieke schijfblokken delen en toch complete, onafhankelijke app-bundels blijven.

Het verwijderen van de Photon-basisapp maakt apps die ervan zijn gemaakt niet onbruikbaar. Het verwijderen van een geïnstalleerde app heeft geen gevolgen voor een andere. Het bestandssysteem regelt het delen, terwijl de apps onafhankelijk blijven.

Digitale ondertekening deed de besparing bijna teniet

Het klonen van de app was maar een deel van de uitdaging. macOS-apps moeten ook digitaal worden ondertekend.

Ons oude bouwproces ondertekende na het aanpassen elke app-bundel volledig opnieuw, inclusief de onderliggende onderdelen. Bij een gewone kopie is dat geen probleem. Bij copy-on-write-opslag kan het wijzigen van een groot binair bestand er echter toe leiden dat APFS er nieuwe fysieke blokken voor moet toewijzen.

Tijdens de ontwikkeling maten we dat het opnieuw ondertekenen van het Electron-framework per app ongeveer 194 MB extra fysieke opslag kostte. We hadden voorkomen dat Electron tijdens het maken van een app werd gekopieerd, om vervolgens bij het ondertekenen toch weer een groot deel ervan te dupliceren.

Daarom moest ook het ondertekeningsproces veranderen.

Het grote, gemeenschappelijke framework wordt nu ondertekend als onderdeel van de Photon-basisapp. Wanneer de desktopapp die basis kloont, laten we de grote gedeelde binaire bestanden ongemoeid en ondertekenen we alleen de kleinere onderdelen opnieuw die daadwerkelijk per app moeten verschillen.

Zodra de app klaar is, voeren we een strikte handtekeningverificatie uit op de voltooide bundel om te controleren of alles geldig blijft.

Zo behouden we zowel de garanties van macOS voor digitale ondertekening als de opslagbesparing van APFS.

Toen Node.js om een kloon vragen geen kloon opleverde

Er was nog een onverwacht probleem: het klonen zelf.

Node.js biedt kopieervlaggen waarmee je copy-on-write kunt aanvragen, waaronder COPYFILE_FICLONE en COPYFILE_FICLONE_FORCE. Op papier leken dat precies de API's die we nodig hadden.

In onze tests met Node.js 24 kopieerden we dezelfde Electron-app van 288 MB op verschillende manieren en maten we hoeveel extra fysieke schijfruimte elke bewerking innam:

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

Beide kloonmodi van Node.js leverden in onze test alsnog een volledige fysieke kopie op. Zelfs de FORCE-variant gaf geen foutmelding toen het verwachte klonen uitbleef.

Het systeemeigen macOS-commando cp -c werkte wel zoals verwacht. Daarom gebruikt de WebCatalog-desktopapp dat mechanisme rechtstreeks.

Het was ook een nuttige herinnering dat je optimalisaties van het bestandssysteem moet controleren door het bestandssysteem zelf te meten. Een API aanroepen die copy-on-write aanvraagt, betekent niet automatisch dat de resulterende bestanden daadwerkelijk fysieke opslag delen.

Zorgen dat de optimalisatie veilig kan mislukken

Schijfruimte besparen is een optimalisatie. Een app met succes installeren is dat niet.

We hebben het nieuwe proces zo ontworpen dat een mislukte kloon de installatie van een app niet verhindert. Als het voorbereiden van de Photon-basisapp mislukt, de basis in de cache beschadigd is, het klonen mislukt of de handtekeningverificatie niet slaagt, valt de desktopapp terug op het vorige bouwproces, met volledig uitpakken en volledig ondertekenen.

In het slechtste geval is het schijfgebruik dus hetzelfde als voorheen; de installatie mislukt niet.

We moesten ook rekening houden met gelijktijdige processen. Een Photon-basisapp wordt eerst in een tijdelijke map voorbereid en pas naar de definitieve locatie verplaatst wanneer ze compleet is. Zo kunnen twee apps die tegelijk worden gebouwd niet per ongeluk een half opgebouwde basis aantreffen.

Oudere basisapps kunnen ook veilig worden verwijderd. Een geïnstalleerde APFS-kloon is er niet van afhankelijk dat de oorspronkelijke basis blijft bestaan. Als de basis wordt verwijderd, behoudt de kloon de fysieke blokken die hij nog gebruikt.

Dit werkt op APFS, het standaardbestandssysteem van elke moderne Mac. Als je apps op een schijf staan die niet kan klonen, zoals een externe HFS+- of exFAT-schijf, valt de WebCatalog-desktopapp terug op een gewone kopie. De apps werken dan zoals voorheen, maar besparen geen ruimte. Voor Windows en Linux verandert er voorlopig niets.

Logische grootte en fysieke grootte zijn niet hetzelfde

Een enigszins verwarrend neveneffect is dat Finder nog steeds kan aangeven dat elke app ongeveer 320 MB groot is.

Dat getal is de logische grootte van de app. De app bevat daadwerkelijk ongeveer 320 MB aan bestanden. Als die bestanden ergens naartoe zouden worden gekopieerd zonder ze te klonen, zou er ongeveer zoveel data moeten worden weggeschreven.

Wat is veranderd, is de fysieke grootte: het aantal unieke blokken dat die bestanden daadwerkelijk op de schijf innemen.

Als twee apps hetzelfde framework van 300 MB bevatten en APFS ze de onderliggende blokken laat delen, kan elke app logisch gezien 300 MB bevatten, terwijl de tweede bijna geen nieuwe fysieke ruimte inneemt.

Het venster Toon info van Finder en hulpmiddelen zoals du maken dit delen niet noodzakelijkerwijs zichtbaar. De besparing is het duidelijkst te zien aan de hoeveelheid vrije ruimte die daadwerkelijk op de schijf overblijft.

We hebben dit gecontroleerd met zeven echte apps: Discord, Facebook, Instagram, Messenger, TikTok en twee aangepaste apps. Op deze manier gebouwd, bespaarden ze ongeveer 1,9 GB schijfruimte ten opzichte van het oude bouwproces.

We hebben ook de onderliggende fysieke schijflocaties gecontroleerd en bevestigd dat de apps hun gemeenschappelijke Electron- en Photon-gegevens op blokniveau deelden. Een app die met het oude bouwproces was gemaakt, deelde geen van die blokken en bood daarmee een nuttig vergelijkingspunt.

Het resultaat

Voor iemand die maar één app maakt met de WebCatalog-desktopapp is het verschil klein. De eerste app gebruikt zelfs iets meer schijfruimte dan voorheen, omdat de desktopapp ook de Photon-basisapp bewaart waarmee latere klonen worden gemaakt.

Daarna neemt het voordeel snel toe.

Voorheen

1 app       ~320 MB
10 apps     >3 GB

Met APFS-klonen:

Nu

1 app       ~340 MB
10 apps     ~360 MB

Nadat de eerste basis is gemaakt, voegt elke extra app doorgaans slechts 1–2 MB aan fysiek schijfgebruik toe.

Het belangrijkste is dat we dit hebben bereikt zonder een afhankelijkheid van een gedeelde runtime te introduceren. Elke app blijft een normale, zelfstandige macOS-app, terwijl APFS de identieke Electron- en Photon-gegevens maar één keer opslaat. Met ongeveer tien geïnstalleerde apps kan dat het daadwerkelijke schijfgebruik met meer dan een factor acht verminderen.

Dit is beschikbaar in de nieuwste versie van de WebCatalog-desktopapp voor macOS. Je hoeft niets in te schakelen: nieuwe apps gebruiken het automatisch en apps die je al hebt, nemen minder ruimte in zodra ze worden bijgewerkt.