Hero Image
Beedaにおけるキャッシュ管理戦略の最適化

高速でシームレスなユーザー体験を提供するためには、すべてのアプリケーションに効果的なキャッシュシステムが必要です。キャッシュがない場合、アセットを繰り返しダウンロードすることで大量のリソースが消費され、読み込み時間が遅延する可能性があります。この問題を解決するために、開発者はパフォーマンスを向上させ、遅延を最小限に抑えるために、ディスクキャッシュ、LRU(Least Recently Used)キャッシュ、データベースキャッシュなど、さまざまなキャッシュ戦略を利用します。 問題: Beeda Userアプリでは、画像、Lottieアニメーション、ビデオといったメディアアセットを効果的に扱うことが、高速でシームレスなユーザー体験を実現するために不可欠でした。それぞれのメディアアセットには、キャッシュや最適化に関する特有のニーズと課題があります。 画像: 高解像度の画像は大量のメモリとストレージを消費する可能性があるため、ディスクキャッシュ(例: URLCacheやSDWebImageのようなサードパーティライブラリを使用)が重要です。 Lottieアニメーション: Lottieファイル(JSONベースのアニメーション)は軽量ですが、効率的なパースとレンダリングが求められます。インメモリキャッシュ(例: NSCache)を使用することで、繰り返しパースする際の負荷を軽減できます。 ビデオ: ビデオはサイズが大きいため、ストリーミングや部分的なキャッシュが必要で、過剰なメモリやストレージの使用を防ぎます。 各キャッシュ機構が特定のメディアタイプに対して効果的である一方で、次のような重要な課題が浮かび上 実装: Beeda Userアプリにおけるメディアアセット管理の課題に対処するため、各タイプに応じた異なるユーティリティ(Utils)を設計しました。この構造化されたアプローチにより、画像、Lottieアニメーション、ビデオなどのアセットを効率的に処理できます。 1. ユーティリティレイヤー (Utils Layer) 各メディアアセットタイプには、それぞれのタスク(ダウンロード、パース、処理など)を担当するユーティリティクラスがあります。これらのユーティリティは、アプリが直接操作することなく、アセットマネージャーからアセットを取得する中間役として機能します。 例えば、画像ユーティリティを考えてみましょう。もし画像がすでにキャッシュされていなければ、このユーティリティはアセットマネージャーのgetDataメソッドを呼び出して画像をダウンロードします。ダウンロードが完了すると、ユーティリティは生データをアセットマネージャーに渡して保存します。 protocol ImageUtilProtocol { func downloadImage(url: String, imageCompletionHandler: ((UIImage) -> Void)?, storageType: StorageType) } 2. アセットマネージャー (Assets Manager) アセットマネージャーはシステム内の中間レイヤーとして機能し、ユーティリティ(Utils)とさまざまなキャッシュメカニズムの間のブリッジとして働きます。主な役割は、指定されたストレージタイプに基づいて、どのキャッシュ方式を使用するかを決定することです。 StorageTypeパラメータは、利用可能なキャッシュメカニズム(例: インメモリ、ディスク、ハイブリッドなど)を定義します。 enum StorageType { case lru(LRUCacheType) case disk } enum LRUCacheType: String { case lottie case image case video } アセットマネージャーには、データを保存および取得するための共通メソッドがあります。 protocol AssetsManagerProtocol { func writeData(data: Data, forKey key: String, storageType: StorageType) func readData(forKey key: String, storageType: StorageType) -> Data? func removeData(forKey key: String, storageType: StorageType) } アセットマネージャーは、キャッシュ操作の管理において重要な役割を果たします。ユーティリティクラスがそのメソッドを呼び出すと、アセットマネージャーはstorageTypeに基づいて適切なキャッシュレイヤーを決定します。その後、データの書き込み、読み取り、または削除といったタスクを該当するキャッシュメカニズムに委任し、効率的かつ正確にアセットを処理します。

Hero Image
BeedaのSwiftコンパイル時間を83%改善

コンテキスト Beedaの新機能拡張に伴い、コンパイル時間が深刻な問題となってきました。些細な変更やフルコンパイルに約11分もかかるため、開発ワークフローに大幅な遅延が生じていました。 生産性を向上させ、開発の効率を改善するために、このコンパイル時間を劇的に短縮することを目指しました。この記事では、どのようにしてコンパイル時間を2分にまで短縮したかを紹介します。 Xcodeの最適化レベル Xcodeでは、以下の3つの最適化レベルから選択できます: なし 高速 全モジュール最適化を使用した高速 これらの設定を活用して、どのようにこの改善を実現したかを紹介します。 「全モジュール最適化」を有効にすることで、コンパイルプロセスが大幅に加速されます。しかし、「高速」または「全モジュール最適化を使用した高速」設定を選択すると、デバッグ機能が無効になります。これらのオプションのいずれかを選択し、アプリをコンパイルした後にデバッグを試みると、コンソールに次のメッセージが表示されます: アプリは最適化されてコンパイルされました - ステッピングは異常に動作する可能性があり、変数が利用できないことがあります。 解決策:ユーザー定義設定を追加する 全モジュール最適化を有効にするには、Xcodeプロジェクトの設定にユーザー定義設定を手動で追加する必要があります。以下はその方法です: 手順 プロジェクト設定に移動: プロジェクトナビゲータでプロジェクトを選択します。 ビルド設定タブに移動します。 ユーザー定義設定を追加: ビルド設定ペインの左上隅にある**+**ボタンをクリックします。 ユーザー定義設定の追加を選択します。 設定名をSWIFT_WHOLE_OPTIMIZATION_LEVEL(または他の関連する名前)にします。 値をYESに設定して、全モジュール最適化を有効にします。 Debug設定でNoneを設定 ターゲットのビルド設定で、Debug構成の最適化レベルをNoneに設定します。 この改善がBeedaに与える影響 コードを頻繁に更新し、反復しているiOSチームにとって、この改善は効率の向上、コストの削減、顧客体験の向上に大きな役割を果たしています。具体的に言うと、1日30回のコンパイルを実行する場合、この最適化は1日に約26時間のコンパイル時間を節約します。この時間の節約は、3人の追加の開発者のアウトプットと同じくらいの効果があります。