"Uygulamanız 200MB'ı aştığı için cellular download yapılamıyor." Bu mesajı gördüğün an, kullanıcıların yarısını kaybettin demektir.
App size, kullanıcı ediniminde kritik bir faktör. Araştırmalar gösteriyor ki her 10MB artış, download oranını %2.5 düşürüyor. Bu rehberde, uygulamanı nasıl küçülteceğini öğreneceksin.
İçindekiler
- Neden App Size Önemli?
- App Size Raporu Oluşturma
- Asset Optimization
- Binary Size Azaltma
- App Thinning
- On-Demand Resources
- Dynamic Library Stratejileri
- Build Settings Optimizasyonu
- Continuous Monitoring
- Gerçek Dünya Case Study
- Sonuç ve Öneriler
Neden App Size Önemli? {#neden-onemli}
Apple'ın koyduğu sınırlar:
Limit | Değer | Sonuç |
|---|---|---|
**Cellular Download** | 200 MB | Üstü sadece WiFi |
**App Store Limit** | 4 GB | Upload red |
**Executable Limit** | 500 MB | Her slice için |
**watchOS Limit** | 75 MB | Daha katı |
İstatistikler
- %50: kullanıcı 100MB+ uygulamaları indirmekten kaçınıyor
- %20: kullanıcı WiFi beklemek yerine vazgeçiyor
- Her 10MB azalma = +2.5% conversion rate
⚠️ Dikkat: App Store'da gördüğün boyut, thinned boyut değil!
App Size Raporu Oluşturma {#size-raporu}
Xcode'un built-in araçlarıyla analiz başla:
Archive ve Export
bash
1# Archive yap2xcodebuild -scheme MyApp -archivePath MyApp.xcarchive archive3 4# Export with app thinning report5xcodebuild -exportArchive \6 -archivePath MyApp.xcarchive \7 -exportPath ./Export \8 -exportOptionsPlist ExportOptions.plistBinary Size Analizi
bash
1# Binary'nin segment dağılımını gör2size -l -m MyApp.app/MyApp3 4# Symbol bilgisi5nm -S MyApp.app/MyApp | sort -k 2 -r | head -50Asset Optimization {#asset-optimization}
Genellikle app size'ın %60-80'i asset'lerden gelir:
Image Compression
bash
1# PNG optimization2pngquant --quality=65-80 --speed 1 --output optimized.png original.png3 4# WebP conversion (iOS 14+)5cwebp -q 80 image.png -o image.webp6 7# JPEG optimization 8jpegoptim --max=80 --strip-all image.jpgAsset Catalog Optimization
Build Settings'de:
- ASSETCATALOG_COMPILER_OPTIMIZATION = space
Asset Catalog'da:
- Sadece gerekli scale'leri ekle (@2x, @3x)
- PDF yerine PNG kullan
- Unused image'ları sil
Vector vs Raster Karar Ağacı
Görsel basit ve tek renk mi?
- EVET → SF Symbol veya PDF kullan
Fotoğraf mı?
- EVET → HEIC/JPEG kullan
- HAYIR → PNG kullan, WebP'ye çevir (iOS 14+)
Binary Size Azaltma {#binary-size}
Dead Code Elimination
swift
1// Build Settings2DEAD_CODE_STRIPPING = YES3STRIP_INSTALLED_PRODUCT = YES4 5// Swift-specific6SWIFT_OPTIMIZATION_LEVEL = -Osize // Release için7 8// Link-Time Optimization9LLVM_LTO = YESSymbol Stripping
swift
1// Build Settings2STRIP_STYLE = all // Release için3DEBUG_INFORMATION_FORMAT = dwarf-with-dsymGenerics Specialization
swift
1// ❌ Her generic kullanımı binary'de duplicate oluşturur2func process<T: Numeric>(_ value: T) -> T {3 return value * 24}5 6// ✅ Protocol-based yaklaşım7protocol Processable {8 static func process(_ value: Self) -> Self9}App Thinning {#app-thinning}
App Thinning, Apple'ın otomatik optimizasyon sistemi:
Slicing
Asset Catalog'da otomatik:
- Sadece hedef cihaza uygun @2x veya @3x
- Sadece hedef architecture (arm64)
- Sadece hedef cihaz özellikleri
Bitcode
swift
1// Build Settings2ENABLE_BITCODE = YESBitcode, App Store'un binary'yi yeniden optimize etmesine izin verir.
On-Demand Resources {#on-demand-resources}
Kullanıcının hemen ihtiyaç duymadığı içerikleri sonra indir:
swift
1class LevelManager {2 private var resourceRequest: NSBundleResourceRequest?3 4 func loadLevel(_ levelTag: String) async throws -> LevelData {5 // Önce cache'i kontrol et6 if Bundle.main.preservationPriority(forTag: levelTag) > 0.5 {7 return try loadLocalLevel(levelTag)8 }9 10 // İndir11 let request = NSBundleResourceRequest(tags: [levelTag])12 self.resourceRequest = request13 14 try await request.beginAccessingResources()15 16 let levelData = try loadLocalLevel(levelTag)17 18 // Cache priority ayarla19 Bundle.main.setPreservationPriority(0.8, forTags: [levelTag])20 21 return levelData22 }23 24 func unloadLevel(_ levelTag: String) {25 resourceRequest?.endAccessingResources()26 resourceRequest = nil27 Bundle.main.setPreservationPriority(0.0, forTags: [levelTag])28 }29}Dynamic Library Stratejileri {#dynamic-library}
Static vs Dynamic
Özellik | Static | Dynamic |
|---|---|---|
**Load Time** | Daha uzun app launch | Lazy load edilebilir |
**Binary Size** | Tek binary, daha büyük | Ayrı .dylib dosyaları |
**Update** | Tüm app güncellenmeli | Sadece library güncellenebilir |
CocoaPods / SPM Optimization
ruby
1# Podfile2use_frameworks! :linkage => :static # Static linkingBuild Settings Optimizasyonu {#build-settings}
Release Build Settings
swift
1// Optimization2SWIFT_OPTIMIZATION_LEVEL = -Osize3GCC_OPTIMIZATION_LEVEL = s4 5// Dead Code6DEAD_CODE_STRIPPING = YES7STRIP_INSTALLED_PRODUCT = YES8STRIP_STYLE = all9COPY_PHASE_STRIP = YES10 11// Link-Time Optimization12LLVM_LTO = YES13 14// Bitcode15ENABLE_BITCODE = YES16 17// Asset Optimization18ASSETCATALOG_COMPILER_OPTIMIZATION = space19 20// Swift21SWIFT_COMPILATION_MODE = wholemoduleContinuous Monitoring {#continuous-monitoring}
Size regression'ları erken yakala:
yaml
1# CI/CD size check2- name: Check Size Limit3 run: |4 SIZE=$(stat -f%z Export/MyApp.ipa)5 MAX_SIZE=200000000 # 200 MB6 if [ $SIZE -gt $MAX_SIZE ]; then7 echo "App size exceeds limit!"8 exit 19 fiGerçek Dünya Case Study {#case-study}
Bir e-ticaret uygulamasını 180MB'dan 65MB'a nasıl düşürdük:
Başlangıç Durumu
- Total: 180 MB
- Assets: 120 MB (67%)
- Binary: 45 MB (25%)
- Other: 15 MB (8%)
Uygulanan Optimizasyonlar
Optimizasyon | Kazanç |
|---|---|
WebP'ye geçiş | -40 MB |
Unused asset temizliği | -25 MB |
On-demand videos | -15 MB |
System fonts kullanımı | -8 MB |
LTO etkinleştirme | -5 MB |
Dead code stripping | -12 MB |
Static linking | -8 MB |
Unused frameworks | -2 MB |
Son Durum
- Total: 65 MB (%64 azalma!)
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
Okuyucu Ödülü
Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var:
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Swift Package Manager Size Impact Analizi {#spm-size-impact}
SPM bağımlılıkları binary size'ı ciddi şekilde şişirebilir. Her package'ın etkisini ölçmek kritik önem taşır.
Package Size Ölçüm Script'i
bash
1# Her SPM dependency'nin binary'ye etkisini ölç2# 1. Tüm bağımlılıklar dahil build3xcodebuild -scheme MyApp -configuration Release build4FULL_SIZE=$(stat -f%z Build/Products/Release-iphoneos/MyApp.app/MyApp)5 6# 2. Şüpheli paketi kaldır, tekrar build et7# Package.swift'ten paketi comment'le8xcodebuild -scheme MyApp -configuration Release clean build9REDUCED_SIZE=$(stat -f%z Build/Products/Release-iphoneos/MyApp.app/MyApp)10 11# 3. Farkı hesapla12echo "Package impact: $(( (FULL_SIZE - REDUCED_SIZE) / 1024 )) KB"Popüler Kütüphanelerin Size Impact'i
Kütüphane | Yaklaşık Binary Etkisi | Alternatif | Alternatif Etkisi |
|---|---|---|---|
**Alamofire** | ~1.2 MB | URLSession wrapper | ~50 KB |
**Kingfisher** | ~800 KB | SDWebImage (lighter) | ~500 KB |
**SnapKit** | ~300 KB | NSLayoutConstraint ext | ~20 KB |
**SwiftyJSON** | ~200 KB | Codable (native) | 0 KB |
**Realm** | ~8 MB | Core Data / SwiftData | 0 KB (system) |
**Firebase Analytics** | ~3.5 MB | Custom analytics | ~100 KB |
**Lottie** | ~1.5 MB | Core Animation | 0 KB (system) |
Lightweight Alternatif Stratejisi
swift
1// ❌ Alamofire (1.2 MB binary impact) - basit API call'lar için overkill2import Alamofire3AF.request("https://api.example.com/data").responseDecodable(of: MyModel.self) { response in4 // ...5}6 7// ✅ Native URLSession extension (50 KB) - aynı iş, minimal overhead8extension URLSession {9 func decode<T: Decodable>(10 _ type: T.Type,11 from url: URL12 ) async throws -> T {13 let (data, response) = try await self.data(from: url)14 guard let httpResponse = response as? HTTPURLResponse,15 (200...299).contains(httpResponse.statusCode) else {16 throw URLError(.badServerResponse)17 }18 return try JSONDecoder().decode(T.self, from: data)19 }20}21 22// Kullanım23let data = try await URLSession.shared.decode(MyModel.self, from: apiURL)Image Format Karşılaştırma ve Seçim Rehberi {#image-format}
Doğru image format seçimi, asset boyutunu %50-70 azaltabilir.
Format Benchmark Sonuçları
Format | 1000x1000px Fotoğraf | 1000x1000px Illustration | Transparency | iOS Desteği |
|---|---|---|---|---|
**PNG** | 2.1 MB | 450 KB | Evet | iOS 2+ |
**JPEG (q80)** | 180 KB | 120 KB | Hayır | iOS 2+ |
**WebP (q80)** | 130 KB | 85 KB | Evet | iOS 14+ |
**HEIC (q80)** | 110 KB | 90 KB | Evet | iOS 11+ |
**AVIF** | 95 KB | 70 KB | Evet | iOS 16+ |
Otomatik Asset Dönüştürme Script'i
bash
1#!/bin/bash2# Tüm PNG asset'leri WebP'ye toplu dönüştür3ASSET_DIR="./Assets.xcassets"4SAVINGS=05 6find "$ASSET_DIR" -name "*.png" -type f | while read file; do7 PNG_SIZE=$(stat -f%z "$file")8 WEBP_FILE="$(echo "$file" | sed 's/.png$//').webp"9 10 cwebp -q 80 -m 6 "$file" -o "$WEBP_FILE" 2>/dev/null11 WEBP_SIZE=$(stat -f%z "$WEBP_FILE")12 13 SAVED=$(( (PNG_SIZE - WEBP_SIZE) / 1024 ))14 echo "$(basename "$file"): $SAVED KB saved"15 SAVINGS=$(( SAVINGS + SAVED ))16done17 18echo "Toplam tasarruf: $SAVINGS KB"Karar Matrisi
Fotoğraf veya gerçekçi görsel mi?
- iOS 16+ hedefliyorsan → AVIF
- iOS 14+ hedefliyorsan → WebP
- iOS 11+ hedefliyorsan → HEIC
- Eski iOS desteği → JPEG
Icon veya basit illustration mu?
- Tek renk, vektörel → SF Symbol (0 KB ek maliyet)
- Çok renkli, küçük → WebP veya PNG (asset catalog optimize eder)
- Animasyonlu → Lottie yerine APNG veya Core Animation
Sonuç ve Öneriler {#sonuc-ve-oneriler}
App size optimization sürekli bir süreç. İşte yol haritası:
- Ölç - Mevcut durumu analiz et
- Önceliklendir - En büyük kazancı verecek alanları belirle
- Uygula - Bir seferde bir optimizasyon
- Doğrula - Her adımda boyutu kontrol et
- Otomatize - CI/CD'ye entegre et
Kaynaklar
- Apple Developer:: [Doing basic optimization to reduce your app's size](https://developer.apple.com/documentation/xcode/doing-basic-optimization-to-reduce-your-app-s-size)
- Apple Developer:: [On-Demand Resources Guide](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/)
- WWDC 2022:: [Improve app size and runtime performance](https://developer.apple.com/videos/play/wwdc2022/110363/)
*Her byte önemli. Kullanıcıların WiFi beklemesine gerek yok.* 📦

