監視サービスを2つ払い続けるのが、ずっと引っかかっていました。EAS Observe が2026年8月20日に正式版(GA)になったと知ったとき、最初に頭に浮かんだのも「これで1本に減らせるのではないか」という期待です。
結論を先に書きます。減らせませんでした。EAS Observe はネイティブクラッシュを取りません。ドキュメントにもはっきり書かれています。
ただ、調べた時間が無駄だったとは思っていません。今まで見えていなかった数字が見えるようになったからです。正式版の告知とドキュメントを突き合わせて確かめたことを、これから入れる方が実際にぶつかる順番で並べ直しておきます。
まず確かめたのは、クラッシュ監視を1本に絞れるかどうか
EAS Observe が扱うのは、本番環境で動いているアプリの起動性能と描画性能です。具体的にはコールドスタート時間、ウォームスタート時間、Time to First Render(最初の描画までの時間)、Time to Interactive(操作できるようになるまでの時間)、バンドル読み込み時間、そして EAS Update のダウンロード時間です。
いずれも、手元の端末では測りようがない数字です。開発機は速く、回線も安定しています。実際の利用者が使っているのは、数年前の Android 端末で、電波の悪い場所かもしれません。その差を埋めるためのサービスだと理解すると、位置づけがはっきりします。
一方で、次の2つは対象外です。
| 項目 | 現在の状況 |
|---|---|
| ネイティブクラッシュ | 未対応。Sentry や BugSnag などのクラッシュレポートサービスを併用する必要があります |
| JavaScript エラー | SDK 57 以降でプレビュー提供。シンボリケート済みのスタックトレースをダッシュボードで確認できます |
私自身、個人開発でいくつかアプリを出していて、そのうち何本かは長く公開しているぶん端末の幅が広くなっています。経験上、本当に痛いのは JavaScript 層まで届かずに落ちるほうです。ネイティブのライブラリ側で落ちると、JS のエラーハンドラは呼ばれません。そこを取ってくれないのであれば、既存のクラッシュレポートは外せない、という判断になりました。
期待と違ったわけですが、書かれ方は誠実でした。「まだ対応していない」と明記し、それまでは別のサービスを使うよう案内しています。曖昧にぼかされているより、はるかに助かります。
無料枠の10万イベントは、どのくらいの規模で尽きるのか
正式版になったタイミングで、料金の枠も確定しました。
| プラン | 月間イベント数 | ダッシュボード |
|---|---|---|
| Free | 100,000 | メインダッシュボードのみ |
| Starter 以上 | 500,000 | 現行および今後追加されるすべて |
含まれる分を超えると、Starter 以上では100万イベントあたり5ドルの従量課金になります。
イベント数だけ言われても規模感がつかみにくいのですが、公式には10万イベントが月間アクティブユーザー1万人程度、50万イベントが5万人程度という目安が添えられています。ここが親切だと感じました。個人開発で最初のアプリを出した直後であれば、無料枠に十分収まります。
私の場合、利用者の少ないアプリから順に入れていく方針にしました。いちばん動いているアプリで試すと、枠の判断と実装の検証が同時に走ってしまい、どちらの判断も雑になります。
データの保持期間については、少し注意が必要です。正式版の告知には「すべてのプランで90日」と書かれています。一方でドキュメントのよくある質問には「最低60日」と書かれています。どちらも公式の記述なので、告知のほうが新しいと読むこともできますが、私は下限として60日を見ておくことにしました。四半期をまたいだ比較をしたい場合は、この差が効いてきます。
入れる手順は3つ。ただし Expo Go では動きません
必要なものは、Expo アカウント、SDK 55 以降、そして EAS プロジェクトとの紐付けです。extra.eas.projectId がアプリの設定に入っていない場合は eas init で作成します。
ここで最初の関門があります。EAS Observe は expo-observe というネイティブライブラリに依存しているため、Expo Go では動きません。開発ビルドか本番ビルドが必要です。Rork で作ったアプリをプレビューだけで触ってきた方にとっては、ここが実質的な入り口になります。
インストールは次の2行です。
npx expo install --fix
npx expo install expo-observe続いてルートレイアウトを包みます。SDK のバージョンで使うコンポーネントの名前が変わる点に気をつけてください。SDK 55 は AppMetricsRoot、SDK 56 以降は ObserveRoot です。
import { Stack } from 'expo-router';
import { ObserveRoot } from 'expo-observe';
function RootLayout() {
return <Stack />;
}
export default ObserveRoot.wrap(RootLayout);この時点で Time to First Render は自動的に測られます。包むだけで最初の数字が取れるのは、導入の心理的な負担が小さくて助かる設計です。
自分のアプリの SDK バージョンが分からない場合は、npx expo-doctor で確認できます。ただし expo-doctor は万能ではなく、見ていない領域もあります。その範囲についてはexpo-doctor の22項目を1つずつ読んだときの記録にまとめています。
markInteractive をひとつの画面にだけ置くと、数字が欠けます
3つ目の手順が markInteractive() の呼び出しです。スプラッシュ画面の裏で行っている初期化——更新確認、ログイン、初期データの取得、スプラッシュのアニメーション——がすべて終わり、利用者が操作できる状態になったところで呼びます。
useEffect(() => {
if (isReady) {
SplashScreen.hide();
markInteractive();
}
}, [isReady, markInteractive]);ここに、ドキュメントの注記としてさらりと書かれている落とし穴があります。
markInteractive() は1セッション中に何度呼んでも安全ですが、記録されるのは最初の1回だけです。そして、アプリに入り口となる画面が複数ある場合——オンボーディング、ログイン、ディープリンクの着地先——そのすべてに置かないと、そこから起動されたセッションの Time to Interactive が記録されません。
これは実務でかなり効きます。ホーム画面ウィジェットや通知から特定の画面へ直接飛ばす作りにしているアプリでは、その経路の数字だけが静かに欠けます。ダッシュボードに数字が並んでいると全部取れている気になりますが、実際には最も体験を左右する経路が抜けている、ということが起こり得ます。
私は壁紙アプリで通知から詳細画面へ直接飛ばす導線を持っているので、ここは読み飛ばさずに済んでよかったと思っています。
もうひとつ、デバッグビルドで集めた数値は既定では送信されません。開発中に動作確認したい場合は configure() で dispatchInDebug を true にします。設定を入れたのに何も出てこない、という最初のつまずきはたいていこれです。
イベント量が増えすぎたときに引けるレバー
正式版の告知にだけ書かれていて、導入ドキュメントには出てこない情報があります。イベント量が想定を超えたときの調整手段です。
ひとつはサンプルレートの調整です。全セッションを送らず、一定の割合だけを送るようにします。利用者数が増えるほど、統計として見るぶんには全数は要りません。
もうひとつは、プロジェクト設定の「Observe data ingestion」から収集そのものを止める方法です。従量課金が始まる仕組みである以上、止め方を知らないまま入れるのは落ち着きません。入れる前に、止め方を確認しておくことをおすすめします。
ターミナルから確認したい場合は eas observe:metrics-summary でバージョンごとの中央値・p75・p95 が出ます。個別に遅いセッションを追いたいときは eas observe:session、経路ごとの数字を見たいときは eas observe:routes です。ダッシュボードを開かずに済むぶん、リリース直後の確認を習慣にしやすい形だと感じました。
次の一歩
まずは利用者の少ないアプリを1本選び、expo-observe を入れて開発ビルドを作ってみてください。数字が出てくるまでに必要なのは、包む1箇所と markInteractive() の1行だけです。そこで初めて、自分のアプリのコールドスタートが実際に何秒なのかが分かります。
そのうえで、既存のクラッシュレポートは当面そのまま残しておいてください。今のところ、置き換えではなく足し算です。
自分のアプリに入っている Expo のバージョンから確かめたい方は、package-lock.json が決めている実際のパッチ版を確認する手順も併せてどうぞ。お読みいただきありがとうございました。