2026 OpenClaw フロント実戦:
プレビュー Webhook → Lighthouse 閾値 → PR 可読要約
想定読者:プレビュー配信のたびに、確定 URL をゲートウェイへ渡し数値ゲートと票の一言を揃えたいフロント。OpenClaw のゲートウェイ Webhookで Ingress を一本化し、リモート Mac で Lighthouse を回し、閾値 JSON と終了コードで CI を安定化。Safari/WebKitは Lighthouse(Chromium ラボ)と分担し短い WebKit スモークへ接続。slug:2026-openclaw-remote-mac-preview-lighthouse-webhook.html。併読:Deployments、Vercel Hook、定期 Lighthouse。
01 ゲートウェイで Hook を受ける理由
「デプロイ完了」通知の形式はバラバラですが、OpenClaw ゲートウェイへ集約すると署名・レート・Idempotency-Key・秘密を一か所に固定できます。受信は 202 Accepted で即返し、OPENCLAW_RUN_ID 付きで Mac ワーカーへ。コールドスタートや Apple GPU 近傍で Lighthouse を再現しやすくなります。
Lighthouse は Chromium のラボ指標、Safari/WebKitは別経路の短いスモークが現実的。同一 Mac で「数値ゲート → WebKit で致命傷」の二段が扱いやすいです。
02 HowTo:再現手順
- Ingress を用意する。共有秘密・HMAC、または mTLS で「自パイプラインからだけ」OpenClaw ゲートウェイへ POST できるようにする。
- 本文を正規化する。
preview_url(必須)、git_sha、pull_request番号、プロバイダ名を抽出。ホストが許可リスト外なら即拒否。 - 冪等キーを付与する。
Idempotency-Key: ${git_sha}:${deploy_or_run_id}:lighthouseをワーカーと Git API の両方で共有し、二重 Hook でジョブが増殖しないようにする。 - ウォームアップする。 HTML と主要バンドルへ、Lighthouse が使う User-Agent に近い
curlで GET。429 は短いバックオフ。 - Lighthouse CLI を実行する。 例:
lighthouse "${PREVIEW_URL}" --only-categories=performance --output=json --output-path=./.openclaw/reports/${OPENCLAW_RUN_ID}.lhr.json --chrome-flags="--headless=new"。Chromium ビルドはロックファイルで固定。 - 閾値 JSON を読み込み比較する。 同一コミット上の
perf/thresholds.json(リポジトリにコミット)を真値と見なし、下表のルールで pass/fail を決める。 - 終了コードで上位オーケストレータへ伝える。 0=合格、2=メトリクス劣化、3=インフラ/タイムアウト。シェルでは
exit "$CODE"。 - PR 要約を返す。 下記 Markdown テンプレを埋め、隠し HTML コメント
<!-- openclaw-lh-preview:${git_sha} -->付きでコメントを upsert。Deployments 行も更新したい場合はDeployments 連鎖稿の API 順序へ合流。 - NDJSON に 1 行。
phase=lighthouse_preview等を.openclaw/reports/hooks.ndjsonへ。
03 閾値表と終了コード
perf/thresholds.json はチーム合意の「下限スコア」と「上限ミリ秒/CLS」を並べた JSON で足ります。解析スクリプトは lhr.json の categories.performance.score、audits.largest-contentful-paint.numericValue 等を抜き出し、下表に照らして判定します。
| 指標 | 例:閾値(プレビュー用) | 劣化時の扱い |
|---|---|---|
| Performance スコア | ≥ 0.85(85 点相当) | 未満なら 終了コード 2(回帰) |
| LCP(秒) | ≤ 2.5s | 超過で 2。ウォームアップ後に再計測してから確定 |
| CLS | ≤ 0.10 | 超過で 2。プレビュー固有の遅延ロードは別タスクへ切り出し可 |
| TBT(ms) | ≤ 300ms | 超過で 2。CPU 争奪時は 3 と誤認しないよう Chromium を固定 |
| 取得不能・タイムアウト | — | 終了コード 3(インフラ)。マージキューは「再実行」ポリシーと組み合わせる |
| すべて閾値内・HTTP 200 | — | 終了コード 0 |
JSON の一例(抜粋):
{
"performance": { "minScore": 0.85 },
"lcpMs": { "max": 2500 },
"cls": { "max": 0.1 },
"tbtMs": { "max": 300 }
}
04 PR 可読要約テンプレ
レビュアが 10 秒で判断できるよう、差分のみを表にし、ログ URL は短命プリサインに限定します。先頭にマーカーを置きます。
<!-- openclaw-lh-preview:${GIT_SHA} -->
### Lighthouse(プレビュー)/${PROVIDER}
| 指標 | 今回 | 閾値 | 結果 |
|------|------|------|------|
| Perf | ${perf_score} | ≥ ${min_perf} | ${perf_ok} |
| LCP | ${lcp_ms} ms | ≤ ${lcp_max} ms | ${lcp_ok} |
- **preview**: ${PREVIEW_URL}
- **run**: \`${OPENCLAW_RUN_ID}\` · exit **${EXIT_CODE}**
- **artifact**: \`.openclaw/reports/${OPENCLAW_RUN_ID}.lhr.json\`
WebKit:${webkit_note}
${webkit_note} には「別ジョブで playwright test --project=webkit 済み」など、実機 Safari 観測の所在を一行で書くと誤解が減ります。
05 FAQ(403/タイムアウト)
| 症状 | 切り分け |
|---|---|
| 403 Forbidden(Lighthouse/curl とも) | Basic/Bearer が必要なプレビュー保護、IP 許可、Geo ブロックを疑う。スモークで使っている 同一ヘッダをゲートウェイから注入するか、リモート Mac の egress IP をホスティング側に登録。 |
| 403 がヘッドレスのみ | ボット判定。User-Agent 固定とウォームアップ Cookie の有無、Referer を揃える。必要なら限定トークンを環境変数経由のみで渡す(PR 本文に貼らない)。 |
| タイムアウト多発 | maxWaitForLoad 引き上げ、同一 OPENCLAW_RUN_ID での1 回だけ再試行、バックグラウンドアプリ停止。連続失敗は 終了コード 3 に寄せ、回帰(2)と混ぜない。 |
| Safari と数値が食い違う | 仕様。Lighthouse は Chromium ラボ値。実機 Safari は短い WebKit スモークや手動サインオフで補強し、PR テンプレにその旨を明記。 |