Jak aplikacja WebCatalog Desktop wykorzystuje klony APFS, aby zmniejszyć zużycie miejsca na dysku przez aplikacje Mac nawet ośmiokrotnie

Aplikacja komputerowa WebCatalog korzysta teraz z klonów APFS w systemie macOS, co znacznie zmniejsza zużycie miejsca na dysku. Ponieważ identyczne dane Electron i Photon są przechowywane tylko raz, każda kolejna aplikacja zajmuje zwykle zaledwie 1–2 MB dodatkowego miejsca na dysku zamiast około 320 MB.

23 września 2026

Nguyen Tran · Software Engineer

Jak aplikacja WebCatalog Desktop wykorzystuje klony APFS, aby zmniejszyć zużycie miejsca na dysku przez aplikacje Mac nawet ośmiokrotnie

Każda aplikacja utworzona za pomocą aplikacji komputerowej WebCatalog zajmowała dotąd na macOS około 320 MB miejsca na dysku. W przypadku aplikacji opartej na Electronie nie jest to nic niezwykłego, ale WebCatalog jest przeznaczony dla osób, które używają wielu aplikacji internetowych jako aplikacji komputerowych. Po zainstalowaniu dziesięciu takich aplikacji mogły one zajmować ponad 3 GB, mimo że większość danych w każdej z nich była dokładnie taka sama.

Niedawno zmieniliśmy sposób, w jaki aplikacja komputerowa WebCatalog tworzy aplikacje na macOS. Pierwsza aplikacja zajmuje teraz około 340 MB fizycznego miejsca na dysku. Wlicza się w to przygotowana kopia silnika aplikacji przechowywana lokalnie. Każda kolejna aplikacja zajmuje zazwyczaj tylko 1–2 MB dodatkowego miejsca. W naszych testach dziesięć aplikacji zajmowało wcześniej ponad 3 GB, a teraz zajmuje około 360 MB.

Osiągnęliśmy to dzięki funkcji wbudowanej w macOS: klonom APFS. Wyzwaniem nie było samo klonowanie plików, lecz zastosowanie go tak, by każda aplikacja pozostała niezależna, miała prawidłowy podpis kodu i działała tak samo jak aplikacja utworzona starym sposobem.

Dlaczego każda aplikacja zajmowała kolejne 320 MB

Aplikacja komputerowa WebCatalog przekształca strony internetowe w samodzielne aplikacje komputerowe. Każda utworzona aplikacja działa na Photonie, naszym silniku aplikacji opartym na Electronie. Na macOS jest to zwykły pakiet .app, zawierający Electrona (Chromium i Node.js), Photona oraz pliki właściwe dla danej aplikacji.

Weźmy na przykład dwie aplikacje: Slack i Discord. Różnią się nazwami, ikonami, identyfikatorami pakietów i konfiguracją, ale duży framework Electron i większość Photona są w nich identyczne.

Dotąd każda aplikacja powstawała jako całkowicie odrębna kopia.

Slack.app
  Electron
  Photon
  Pliki właściwe dla Slacka

Discord.app
  Electron
  Photon
  Pliki właściwe dla Discorda

Framework Electron i Photon mogły być w obu aplikacjach identyczne co do bajta, ale macOS i tak przechowywał kolejną fizyczną kopię dla każdej aplikacji. Dziesięć aplikacji oznaczało więc mniej więcej dziesięć kopii niemal tego samego pakietu o wielkości 320 MB.

Ta architektura miała jednak cechę, którą chcieliśmy zachować: każda aplikacja była w pełni niezależna. Usunięcie jednej nie mogło wpłynąć na pozostałe, a zainstalowane aplikacje nie wymagały, by aplikacja komputerowa WebCatalog nadal znajdowała się w systemie.

Chcieliśmy pozbyć się jedynie niepotrzebnego powielania danych.

APFS oferował już mechanizm, którego potrzebowaliśmy

Współczesne komputery Mac korzystają z systemu plików APFS firmy Apple. APFS obsługuje klonowanie — mechanizm kopiowania przy zapisie, dzięki któremu dwa niezależne pliki mogą współdzielić te same dane fizyczne, dopóki jeden z nich się nie zmieni.

Wyobraźmy sobie kopiowanie pliku o wielkości 300 MB. Przy zwykłym kopiowaniu macOS zapisuje na dysku kolejne 300 MB, więc oba pliki zajmują łącznie około 600 MB.

W przypadku klonu APFS nowy plik nadal wygląda i zachowuje się jak kompletny plik o wielkości 300 MB, ale początkowo wskazuje na te same bloki fizyczne co oryginał.

Plik A ────┐
            ├── współdzielone bloki fizyczne
Plik B ────┘

Jeśli później zmieni się część pliku B, APFS zapisze nowe bloki tylko dla zmienionych danych. Wszystko, co pozostanie identyczne, może nadal współdzielić pierwotne bloki.

Plik A ──────── współdzielone bloki

Plik B ──────── współdzielone bloki
       └─────── zmienione bloki

Z punktu widzenia aplikacji pliki A i B są oddzielnymi plikami. Z punktu widzenia dysku SSD identyczne dane wystarczy przechować raz.

To niemal dokładnie odpowiadało naszym potrzebom.

Tworzenie aplikacji ze wspólnej bazy

Aplikacja komputerowa WebCatalog przygotowuje teraz bazę dla każdej kombinacji wersji Electrona i Photona. Bazowa aplikacja Photona zawiera elementy identyczne we wszystkich aplikacjach, w tym Electrona, Photona, strukturę frameworka i wspólne podpisy.

Kiedy aplikacja komputerowa tworzy kolejną aplikację z użyciem tych samych wersji, nie rozpakowuje już i nie buduje od zera następnej pełnej kopii. Zamiast tego tworzy klon APFS bazowej aplikacji Photona i dostosowuje tylko te elementy, które muszą się różnić.

Należą do nich nazwa i ikona aplikacji, identyfikator pakietu, ustawienia, nazwy plików wykonywalnych, identyfikator kompilacji oraz inne metadane właściwe dla danej aplikacji.

Ponieważ większość pakietu pozostaje bez zmian, APFS nadal współdzieli bloki fizyczne zawierające Electrona i Photona. Nowe miejsce zajmuje tylko stosunkowo niewielka ilość danych właściwych dla aplikacji.

Dlaczego nie współdzielić po prostu Electrona?

Bardziej oczywistym rozwiązaniem byłoby zainstalowanie Electrona raz i skierowanie do niego wszystkich aplikacji.

Rozważaliśmy to, ale zasadniczo zmieniłoby to model niezawodności. Gdyby współdzielona instalacja Electrona zniknęła, każda zależna od niej aplikacja mogłaby przestać działać. Mógłby ją usunąć program do czyszczenia pamięci podręcznej albo deinstalacja aplikacji komputerowej WebCatalog. Przenoszenie lub przywracanie pojedynczej aplikacji również stałoby się bardziej skomplikowane.

Wymagałoby to także śledzenia, które zainstalowane aplikacje zależą od których wersji środowiska uruchomieniowego, aby móc bezpiecznie usuwać stare wersje.

Podpisywanie kodu w macOS stwarza kolejny problem. Rygorystyczna weryfikacja podpisu odrzuca dowiązania symboliczne prowadzące poza pakiet aplikacji.

Klony APFS dają nam korzyści wynikające ze współdzielenia danych bez wprowadzania takiej zależności. Zainstalowane aplikacje mogą współdzielić fizyczne bloki dysku, pozostając kompletnymi, niezależnymi pakietami.

Usunięcie bazowej aplikacji Photona nie psuje aplikacji z niej utworzonych. Usunięcie jednej zainstalowanej aplikacji nie wpływa na inną. Współdzieleniem zajmuje się system plików, a architektura aplikacji pozostaje niezależna.

Podpisywanie kodu omal nie zniwelowało oszczędności

Sklonowanie aplikacji było tylko częścią wyzwania. Aplikacje na macOS muszą mieć także podpisany kod.

W naszym starym procesie po dostosowaniu aplikacji ponownie podpisywaliśmy cały jej pakiet, łącznie z elementami zagnieżdżonymi. Przy zwykłej kopii nie stanowi to problemu. Jednak w przypadku mechanizmu kopiowania przy zapisie modyfikacja dużego pliku binarnego może spowodować, że APFS przydzieli mu nowe bloki fizyczne.

Podczas prac zmierzyliśmy, że ponowne podpisanie frameworka Electron zwiększało fizyczne zużycie miejsca o około 194 MB na aplikację. Udało nam się uniknąć kopiowania Electrona podczas tworzenia aplikacji, tylko po to, by ponownie powielić znaczną jego część przy podpisywaniu.

Musieliśmy więc zmienić również sposób podpisywania.

Duży, wspólny framework jest teraz podpisywany jako część bazowej aplikacji Photona. Gdy aplikacja komputerowa klonuje tę bazę, unikamy modyfikowania dużych, współdzielonych plików binarnych i ponownie podpisujemy tylko mniejsze elementy, które rzeczywiście muszą się różnić między aplikacjami.

Po ukończeniu aplikacji przeprowadzamy rygorystyczną weryfikację podpisu gotowego pakietu, aby upewnić się, że wszystko pozostaje prawidłowe.

Dzięki temu zachowujemy zarówno gwarancje wynikające z podpisywania kodu w macOS, jak i oszczędności miejsca zapewniane przez APFS.

Gdy polecenie klonowania w Node.js wcale nie klonowało

Pojawił się jeszcze jeden nieoczekiwany problem: samo wykonanie klonu.

Node.js udostępnia flagi kopiowania służące do żądania kopiowania przy zapisie, w tym COPYFILE_FICLONE i COPYFILE_FICLONE_FORCE. Teoretycznie wyglądały na dokładnie te mechanizmy API, których potrzebowaliśmy.

W naszych testach na Node.js 24 skopiowaliśmy tę samą aplikację Electron o wielkości 288 MB kilkoma metodami i zmierzyliśmy, ile dodatkowego fizycznego miejsca na dysku zajęła każda operacja:

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

W naszym teście oba tryby klonowania Node.js nadal tworzyły pełną fizyczną kopię. Nawet wariant FORCE nie zgłaszał błędu, choć oczekiwane klonowanie nie nastąpiło.

Natywne polecenie macOS cp -c zadziałało zgodnie z oczekiwaniami, dlatego aplikacja komputerowa WebCatalog korzysta bezpośrednio z tego mechanizmu.

Było to również przydatne przypomnienie, że optymalizacje systemu plików należy sprawdzać, mierząc działanie samego systemu plików. Wywołanie API żądającego kopiowania przy zapisie nie oznacza jeszcze, że powstałe pliki rzeczywiście współdzielą fizyczne miejsce na dysku.

Optymalizacja, której niepowodzenie nie przerywa instalacji

Oszczędzanie miejsca na dysku jest optymalizacją. Pomyślne zainstalowanie aplikacji nią nie jest.

Zaprojektowaliśmy nowy proces tak, aby niepowodzenie klonowania nie uniemożliwiało instalacji. Jeśli nie uda się przygotować bazowej aplikacji Photona, baza w pamięci podręcznej będzie uszkodzona, klonowanie się nie powiedzie lub weryfikacja podpisu nie zakończy się pomyślnie, aplikacja komputerowa wróci do poprzedniego sposobu tworzenia aplikacji, obejmującego pełne rozpakowanie i podpisanie.

W najgorszym przypadku aplikacja zajmie więc tyle miejsca co wcześniej — instalacja nie zakończy się niepowodzeniem.

Musieliśmy też uwzględnić równoczesne operacje. Bazowa aplikacja Photona jest najpierw przygotowywana w katalogu tymczasowym i przenoszona do docelowej lokalizacji dopiero wtedy, gdy jest kompletna. Dzięki temu dwa procesy tworzenia aplikacji działające jednocześnie nie mogą przypadkiem skorzystać z niedokończonej bazy.

Starsze bazy również można bezpiecznie usuwać. Zainstalowany klon APFS nie potrzebuje oryginalnej bazy do dalszego działania. Jeśli baza zostanie usunięta, klon zachowa bloki fizyczne, z których nadal korzysta.

Rozwiązanie działa na APFS, domyślnym systemie plików każdego współczesnego komputera Mac. Jeśli Twoje aplikacje znajdują się na dysku, na którym klonowanie nie jest możliwe — na przykład na zewnętrznym dysku HFS+ lub exFAT — aplikacja komputerowa WebCatalog użyje zwykłego kopiowania. Aplikacje będą działać jak wcześniej, ale nie zaoszczędzą miejsca. Na razie nic nie zmienia się w systemach Windows i Linux.

Rozmiar logiczny i fizyczny to nie to samo

Nieco mylący efekt uboczny jest taki, że Finder może nadal pokazywać, iż każda aplikacja ma około 320 MB.

Ta liczba oznacza rozmiar logiczny aplikacji. Aplikacja rzeczywiście zawiera około 320 MB plików i gdyby skopiować je gdzieś bez klonowania, trzeba byłoby zapisać mniej więcej tyle danych.

Zmienił się rozmiar fizyczny, czyli liczba unikalnych bloków, które te pliki faktycznie zajmują na dysku.

Jeśli dwie aplikacje zawierają ten sam framework o wielkości 300 MB, a APFS pozwala im współdzielić te same bloki, każda z nich może logicznie zawierać 300 MB, choć druga niemal nie zwiększa ilości fizycznie przechowywanych danych.

Widok „Pobierz informacje” w Finderze i narzędzia takie jak du niekoniecznie pokazują to współdzielenie. Oszczędności najlepiej widać w ilości wolnego miejsca, które faktycznie pozostało na dysku.

Sprawdziliśmy to na siedmiu rzeczywistych aplikacjach: Discordzie, Facebooku, Instagramie, Messengerze, TikToku i dwóch aplikacjach niestandardowych. Utworzone w ten sposób zajęły około 1,9 GB mniej miejsca na dysku niż przy użyciu starego procesu.

Sprawdziliśmy również położenie danych na dysku i potwierdziliśmy, że aplikacje współdzieliły wspólne dane Electrona i Photona na poziomie bloków. Aplikacja utworzona starym sposobem nie współdzieliła żadnego z tych bloków, co dało nam użyteczny punkt odniesienia.

Rezultat

Dla osoby, która tworzy tylko jedną aplikację za pomocą aplikacji komputerowej WebCatalog, różnica jest niewielka. Pierwsza aplikacja zajmuje nawet nieco więcej miejsca niż wcześniej, ponieważ aplikacja komputerowa przechowuje także bazową aplikację Photona, z której powstają kolejne klony.

Potem korzyści szybko rosną.

Wcześniej

1 aplikacja       ~320 MB
10 aplikacji      >3 GB

Z klonowaniem APFS:

Teraz

1 aplikacja       ~340 MB
10 aplikacji      ~360 MB

Po utworzeniu początkowej bazy każda kolejna aplikacja zajmuje zazwyczaj tylko 1–2 MB dodatkowego fizycznego miejsca na dysku.

Co ważne, osiągnęliśmy to bez wprowadzania zależności od współdzielonego środowiska uruchomieniowego. Każda aplikacja pozostaje zwykłą, samodzielną aplikacją na macOS, a APFS przechowuje identyczne dane Electrona i Photona tylko raz. Przy około dziesięciu zainstalowanych aplikacjach może to zmniejszyć faktyczne zużycie miejsca na dysku ponad ośmiokrotnie.

Ta funkcja jest dostępna w najnowszej wersji aplikacji komputerowej WebCatalog na macOS. Nie trzeba niczego włączać: nowe aplikacje korzystają z niej automatycznie, a aplikacje już zainstalowane zaczną zajmować mniej miejsca przy następnej aktualizacji.