こんにちは!個人開発者 兼 ZOZO社員のツヅキ(@tsuzuki817)です!
今回はSwiftUIのプレビューが遅すぎて困っている方に朗報です。プレビュー専用のTargetを作ることで、プレビューの表示速度を劇的に改善できたので、その方法を共有します。
この記事はZOZO Advent Calendar 2025の14日目の記事です。
TL;DR
- SwiftUIのプレビューが遅い原因は重い依存関係(Firebase等)のビルド
- プレビュー専用の軽量Targetを作ることでプレビュー速度が約X倍に改善
- 設定は10分程度で完了
はじめに:作っているアプリの紹介
まずは宣伝させてください!
私は「旅行思い出マップ」というiOSアプリを個人開発しています🗺️
このアプリは、訪れた場所を地図上に記録して、思い出を振り返ることができるアプリです。都道府県単位で訪問した市町村を塗りつぶしていく機能があり、日本全国制覇を目指すユーザーさんも多いです。
よければダウンロードしてみてね!
課題:プレビューが遅すぎる問題
メインアプリの依存パッケージ
- Firebase SDK(Auth, Firestore, Storage, Analytics, Crashlytics, Messaging, RemoteConfig)
- Google Mobile Ads
- Google Sign In
- SDWebImageSwiftUI
- Lottie
- その他自作ライブラリ
特にFirebase SDKが曲者で、このパッケージ群がビルドに時間がかかります。
SwiftUIのプレビューは、対象のファイルが所属するTargetをビルドしてから表示されます。つまり、メインアプリのTargetでプレビューを表示しようとすると...
- Firebase SDKをビルド
- Google Mobile Adsをビルド
- その他全ての依存関係をビルド
- メインアプリのソースをビルド
- やっとプレビューが表示される
めちゃくちゃ遅い!!
ちょっとした UI の調整をしたいだけなのに、毎回何十秒も待たされるのは開発効率が落ちすぎます。
解決策:プレビュー専用Targetを作る
そこで考えたのが、プレビュー専用の軽量Targetを作ること。
アイデア
- メインアプリとは別のTargetを作成
- 依存関係は必要最小限に絞る
- プレビューを見たいViewをこのTargetに追加
こうすることで、Firebase などの重い依存関係をビルドせずに、プレビューを表示できるようになります。
依存関係の比較
| Target | 依存パッケージ |
|---|---|
| OmoideMap(メイン) | Firebase SDK(7種), Google Mobile Ads, Google Sign In, SDWebImageSwiftUI, Lottie, TsuzuKit, IndicatorKun |
| OMPreview(プレビュー用) | SDWebImageSwiftUI, TsuzuKit |
約10個 → 2個 に削減!
作り方
Step 1: 新しいTargetを追加
- Xcodeでプロジェクトを開く
- File → New → Target を選択
- App テンプレートを選択
- 名前を入力(例:
OMPreview)
Step 2: 依存関係を最小限に設定
- 作成したTargetを選択
- 「General」タブの「Frameworks, Libraries, and Embedded Content」を確認
- プレビューに必要な最小限のライブラリのみを追加
私の場合は以下だけを追加しました:
-
SDWebImageSwiftUI(画像表示に必要) -
TsuzuKit(自作ユーティリティ)
Firebase SDKは追加しません!
Step 3: プレビュー対象のソースファイルをTarget Membershipに追加
プレビューを表示したいSwiftファイルを、新しいTargetのTarget Membershipに追加します。
- プレビューしたいファイルを選択
- File Inspectorを開く(右側のパネル)
- 「Target Membership」で
OMPreviewにチェック
注意: ViewModelやUseCaseなど、Viewが依存するファイルも一緒にTarget Membershipに追加する必要があります。
ただし、Firebaseを直接使用しているファイルは追加できません(ビルドエラーになります)。そのため、プレビュー用のモックを用意するか、プレビューできる範囲をUI層に限定する必要があります。
Step 4: Targetを切り替えてプレビュー
- Xcodeのスキームを
OMPreviewに切り替え - プレビューしたいファイルを開く
- Canvas(プレビュー)を表示
これでFirebaseなどの重い依存をビルドせずに、プレビューが表示されます!
効果測定
実際にどのくらい速くなったのか計測してみました。
計測環境
- MacBook Air 13インチ(M4)
- Xcode 26.1.1
- iOS 26.1 Simulator
結果
| 項目 | メインTarget | プレビュー専用Target | 高速化 |
|---|---|---|---|
| CleanBuild後 プレビュー表示 |
111.3秒 | 20.9秒 | 約5.3倍 |
| インクリメンタルビルド後 プレビュー表示 |
61.1秒 | 4.1秒 | 約14.9倍 |
約15倍の高速化を達成!
なぜ速くなるのか
SwiftUIのプレビューが表示されるまでの流れを理解すると、なぜこの方法で速くなるかがわかります。
プレビュー表示の仕組み
- 依存パッケージのビルド:SPMの依存関係を全てビルド
- ソースコードのコンパイル:Targetに含まれるSwiftファイルをコンパイル
- プレビュー用バイナリの生成:プレビュー表示用の実行ファイルを作成
- シミュレータで実行:作成したバイナリをシミュレータで実行してレンダリング
このうち、Step 1の依存パッケージのビルドが最も時間がかかります。
Firebase SDKは内部で大量のソースコードを持っており、これをコンパイルするだけで相当な時間がかかります。Google Mobile Adsも同様です。
プレビュー専用Targetでは、これらの重い依存を含めないため、Step 1がほぼスキップされます。結果として、プレビュー表示が劇的に速くなるわけです。
メインTarget:
Firebase(大) + GoogleAds(大) + 自作コード(小) = 遅い
プレビューTarget:
SDWebImage(中) + 自作コード(小) = 速い
注意点・デメリット
この方法にはいくつかの注意点があります。
1. Target Membershipの管理が必要
プレビューしたいファイルごとに、Target Membershipを追加する必要があります。ファイル数が多いと面倒です。
対策: よくプレビューするUI層のファイルだけを追加しておく
2. Firebaseを使うコードはプレビューできない
Repository層やUseCase層で直接Firebaseを使っているファイルは、プレビュー専用Targetには追加できません(ビルドエラーになるため)。
対策:
- MVVM + UseCaseアーキテクチャを採用し、View層をFirebaseから分離する
- プレビュー用のモック/スタブを用意する
3. 両方のTargetを意識する必要がある
開発中にTargetを切り替える必要があり、今どちらのTargetで作業しているか意識する必要があります。
対策:
- UIの調整時はプレビューTarget
- 実機テスト時はメインTarget
- というルールを決めておく
よくある質問
Q: 全部のファイルをTarget Membershipに追加すべき?
A: いいえ。よくプレビューするファイル(View層)だけで十分です。
全てのファイルを追加すると管理が大変になるので、UI調整をよく行うViewファイルに絞ることをおすすめします。
Q: Xcode 16のファイルシステム同期機能と相性は?
A: 問題なく使えます。
プレビュー専用Targetは独自のフォルダ(OMPreview/)を持つので、メインアプリのファイルシステム同期とは別に管理されます。
Q: Swift Package Managerのライブラリはどうなる?
A: Target単位で追加するライブラリを選べます。
プロジェクト設定の「Package Dependencies」でパッケージを追加した後、各Targetの「Frameworks, Libraries, and Embedded Content」で使用するパッケージを選択できます。
まとめ
SwiftUIのプレビューが遅くて困っている方は、プレビュー専用の軽量Targetを作ることで大幅に改善できます。
特にFirebase SDKを使っているアプリでは効果絶大です。
設定は10分程度で完了するので、ぜひ試してみてください!
この記事のポイント
- プレビューが遅い原因は重い依存関係のビルド
- 別Targetを作って依存を最小限にすることで高速化
- Target Membershipで必要なファイルだけ追加
- 約X倍の高速化を達成
最後に
もし「おもいでマップ」に興味を持っていただけたら、ぜひダウンロードして使ってみてください!
また、この記事が参考になったら、いいねやストックをいただけると励みになります!
質問やフィードバックがあれば、コメントやTwitter(X)(@tsuzuki817)でお気軽にどうぞ!






