Xcode Organizer の Hang Report は、私にとって長らく「気が向いたときに開く窓」でした。クラッシュは Crashlytics が毎日通知してくれますが、ハング(一定時間 UI が固まる現象)は静かに溜まっていきます。個人開発で複数の壁紙アプリを運用していると、クラッシュ率や売上のように毎日眺める指標はいつの間にか習慣になりますが、ハングは「ストアの評価に効くと分かっているのに、見る習慣を作りそびれた指標」の代表でした。今年に入ってから、Xcode Organizer の Hang Report を毎週金曜の30分だけ見る、という運用に切り替えてみました。本稿はその1ヶ月の所感です。
なぜ「毎日見ない」と決めたか
最初は Crashlytics と同じく、毎朝確認する運用にしようとしました。実際に1週間試して、すぐにやめました。Hang Report の数値は時間粒度が粗く、毎日見ても数字がほとんど動かないからです。Crashlytics は1日単位で「昨日のクラッシュ率は◯%」と読めますが、Hang Report は「直近30日のハング率」を主に出してくるので、日次でチェックしても判断が変わりません。
頻度を落とそうとした結果、毎週金曜の30分という形に落ち着きました。金曜にしたのは、週末の作業ブロックに入る前に「もしハング率が悪化していたら来週の作業順序を変える」と決めるためです。新しい観測の習慣は最小頻度から始めて、データが必要だと言ったときだけ頻度を上げる、というのが個人開発で何度も学んだやり方です。毎日見るほどの分量がない指標を無理に毎日のルーティンへ押し込むと、結局どのルーティンも続かなくなるからです。
毎週金曜の30分で実際にやっていること
金曜の14時から14時半を Hang Report のスロットにしています。やっていることは3つだけです。
第一に、Xcode を起動して Window → Organizer → Disk Writes / Hangs タブを開きます。アプリは現在6本(壁紙系4本、癒し系2本)並列で運用しているので、左ペインのプロジェクトを順に切り替えて、それぞれの直近30日のハング率を読みます。基準は「直近1週間の数字が、その前の3週間の平均より明らかに上振れしているかどうか」だけです。具体的な閾値で機械的に判定はしません。アプリごとに普段の値が違うので、相対的な変化のほうが意味があると感じています。
第二に、上振れしているアプリがあれば、その週に上位3つの Hang signature を開きます。Xcode はスタックトレースの上位フレームを並べてくれるので、それを眺めて「アセット読込起因なのか、ネットワーク待ち起因なのか、メインスレッドでの画像処理起因なのか」だけ大雑把に分類します。修正方針は金曜の30分の中では決めません。月曜以降の作業候補としてメモに入れるだけです。
第三に、6本まとめて見たときに同じ Hang signature が複数アプリで出ていないかを確認します。共通の壁紙描画コードや、共通のサブスク復元コードに起因するハングがあると、1本の修正で6本が改善する可能性があります。これは個人開発で複数アプリを並列に運用しているからこそ気づける視点で、AdMob のメディエーション最適化のときにも似たことを感じました。
Crashlytics との役割分担をどう整理したか
Hang Report を見始めて最初にぶつかったのが、「これは Crashlytics のフリーズ系イベントと何が違うのか」という疑問でした。1ヶ月運用してみての整理は、次のような形に落ち着いています。
Crashlytics は、アプリが本当に落ちた(プロセスがクラッシュした)事象を高い粒度で集めてくれます。Velocity Alert もあり、急増を検知して即時に通知できます。一方で「2秒間 UI が止まったが、その後復帰した」という体験は Crashlytics の主な守備範囲ではありません。これを集計してくれるのが Xcode Organizer の Hang Report です。
つまり、私の運用上は次のように住み分けています。Crashlytics は「致命傷の即時検知」用、Hang Report は「ストア評価に効くじわじわ系の体感悪化の発見」用。前者は通知ベースで Claude in Chrome にも一部の整理を任せていますが、後者は通知も来ないし AI に整理を任せるほどの分量も出ないため、人間が金曜にまとめて読む、という形が一番素直でした。
ハングは、レビューの「重い」「カクつく」というコメントに直結します。レビュー文面と Hang Report の数字を並べると、ユーザーが感じている重さの正体がデータ側でも確認できる、という瞬間が何度かありました。これは Crashlytics だけ見ていた頃には届かなかった気づきです。
1ヶ月で実際に手を入れた箇所
数字としては、6本のうち3本でハング率が直近1週間に少しずつ上昇していた、というのが1ヶ月の集計結果でした。そのうち2本は壁紙のサムネイル一覧画面で、共通の画像キャッシュコードがメインスレッドでデコードしていたことが原因でした。バックグラウンドキューでデコードしてからメインスレッドに戻す、という単純な書き換えだけでハング率が半分以下に下がりました。
もう1本は癒し系のアプリで、起動直後のスプラッシュ画面で広告 SDK の初期化を同期的に呼んでいたのが原因でした。AdMob の SDK 初期化は完了コールバックを返してくれるので、UI 描画と並行に走らせる形に組み替えました。これはアプリの起動時間そのものにも効き、AdMob の eCPM にもわずかですが好影響が出ました(広告が出るまでの時間が短くなり、初回 impression の取りこぼしが減ったため)。
修正後にハング率が改善したかどうかも、翌週の金曜にまとめて確認します。1週間あけて見るのは、Xcode Organizer の集計が反映されるまでに数日かかるためです。即時の検証には向きませんが、その分「直したつもりで満足する」というよくある失敗を避けやすい仕組みになっています。
続けるための小さな工夫
1ヶ月続けてみての小さな工夫を3つ書いておきます。
第一に、金曜14時にカレンダー登録しています。これがないと、急ぎの作業に飲み込まれて忘れます。30分のスロットを取るだけで、Xcode を開く心理的な敷居が下がりました。
第二に、メモはアプリごとに1ファイルにまとめています。Markdown ファイルを6本(アプリの数だけ)作って、見出しを「2026-W18」「2026-W19」のように週番号で並べています。毎週同じファイルに追記していくので、3週間前の自分が何を気にしていたかが横並びで見えます。Xcode 内のメモ機能ではなく外部ファイルにしているのは、Xcode を閉じている平日にも読み返せるようにするためです。
第三に、修正候補は「今週着手する」「来月見直す」「保留」の3段で分けます。Hang Report で見えるハングのうち、本当に着手すべきものは多くありません。直近で増えていないものや、影響ユーザー数が小さいものは保留に回します。一度に全部を直そうとしないと先に決めておくと、結果的に毎週コンスタントに着手できる量に収まり、6本を並列で運用していても破綻しません。
ハングが見えるようになって変わった意識
Hang Report の数字を毎週見るようになって、コードを書くときの意識が少し変わりました。たとえば新しい画面を作るときに、メインスレッドで何をしているかを以前より意識します。画像のサイズ計算、JSON のパース、設定値の取り出し、こうした小さな処理がメインスレッドで連鎖すると体感に響く、ということが Hang Report の数字を通して実感できるようになったためです。
「ユーザーが画面を触ってから、何ミリ秒で反応が返るか」という時間軸の感覚が、数字を毎週眺めるうちに自分の中で少しずつ更新されていく感触があります。以前は描画の見た目が整っていれば満足していた場面でも、いまは指が触れてから反応が返るまでの間に何が走っているかを先に考えるようになりました。観測の習慣が、設計判断の枠そのものを静かに変えていきます。
次に取り組むこと
直近で試したいのは、Xcode Organizer の Hang Report と App Store のレビュー本文を並べて読む運用です。レビューに「重い」「もっさり」「固まる」という言葉が出てきた週と、Hang Report が悪化した週が一致するかを検証してみたいと考えています。一致が確認できれば、レビューを Claude in Chrome に分類させて、Hang Report と突き合わせるダッシュボードを作るのが次のステップになりそうです。
長く続くアプリを作っていくためには、派手な指標だけでなく、こうしたじわじわ系の数字と仲良くする習慣が要ると感じています。同じように個人開発で複数アプリを回している方の参考になれば嬉しく思います。