CrUX 數據查詢的五個入口:從 API 到 BigQuery 該選哪個
CrUX 數據查詢有 API、History API、CrUX Vis、PageSpeed Insights、BigQuery 五個入口,工程師最常卡在「我這個網站到底有沒有資料、要去哪撈」。這篇用一張決策矩陣 + curl 範例 + JSON 解讀,把 Chrome 使用者體驗報告的查詢方式講到能直接動手用。
陳柏翰
網站效能工程師
如果只是要快速判斷單一 URL 的 CrUX 與 lab data 狀態,可以先用 PageSpeed Insights 報表判讀流程 做第一輪診斷,再決定是否進一步查 CrUX API 或 BigQuery。
CrUX 數據查詢的五個入口,工程師該選哪一個
CrUX 數據查詢有五個入口:CrUX API、CrUX History API、CrUX Vis、PageSpeed Insights、BigQuery。先選對入口,再寫第一行 code,會比直接 google「crux api 範例」少走一個小時冤枉路。每個入口的時間粒度、上手成本、樣本門檻都不同,混用會看到不一致的數字。
這個站把五個入口放成同一張表,是因為前陣子有同事問我,他用 PageSpeed Insights 看到 LCP 是 3.2s,但用 CrUX API 撈出來 p75 變 2.4s,他以為其中一個壞了。其實只是兩個工具撈的資料粒度不一樣。在動手之前先看清楚這張表,後面就不會在不同數字之間繞來繞去。
| 入口 | 適合場景 | 時間粒度 | 上手成本 | 樣本量門檻 |
|---|---|---|---|---|
| CrUX API | 單次撈某個 URL 或 origin 的當前 28 天 p75 | 當下快照(28 天滾動) | 低(一行 curl) | 需 API key + 站點達門檻 |
| CrUX History API | 看半年趨勢,揪出某次發版後的回歸 | 每週一筆,最多 25 週 | 低(同 API key) | 需 API key + 站點達門檻 |
| CrUX Vis | 不想寫 code,UI 上點兩下就看走勢 | 每週一筆 | 無門檻 | 站點達門檻才看得到 |
| PageSpeed Insights | 順便跑一次 Lighthouse 並看 CrUX 摘要 | 當下快照 | 無門檻 | 未達門檻只剩 lab data |
| BigQuery (chrome-ux-report) | 大規模跨站、跨國家、跨月分析 | 每月一張表 | 高(要寫 SQL,要顧成本) | 需 GCP 專案,站點仍需達門檻 |
選擇邏輯很直覺:只想看自家某個頁面現在的分數,去 PageSpeed Insights;想撈進自家 dashboard 自動化,用 CrUX API;要看趨勢看回歸,CrUX History API;要做一次大規模的競品比較,BigQuery。如果還對 LCP、INP、CLS 三個指標的定義有些模糊,先補一下 Core Web Vitals(想知道這些 CrUX 數據如何反映到 SEO 排名訊號,可以看CWV 對 SEO 排名的真實影響) 三指標技術定義,這樣等下解讀 histogram 才不會卡住。
用 CrUX API 撈單次資料:curl 範例與回應 JSON 解讀
CrUX API 的核心動作只有兩個:拿 API key、發一個 POST 給 queryRecord 端點,body 裡指定 origin 或 url、裝置別 formFactor、想看的 metrics。回傳會是一個 JSON,裡面有 histogram 三段、percentiles 的 p75,跟 collection period 的時間範圍。
申請 API key 的步驟略,去 Chrome 官方 CrUX API 使用指南裡面有逐步畫面。下面這段 curl 是查一個 origin 在桌機環境的 LCP、INP、CLS:
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=API_KEY" \
-H "Content-Type: application/json" \
--data '{
"origin": "https://web.dev",
"formFactor": "DESKTOP",
"metrics": ["largest_contentful_paint", "interaction_to_next_paint", "cumulative_layout_shift"]
}'
實際回傳會長像下面這樣(節選 LCP 部分)。看 JSON 的時候有兩個欄位最有用:histogram 給你 Good / Needs Improvement / Poor 三段的分布比例,percentiles.p75 才是 Google 拿來判斷你的網站及格沒的數字。
{
"record": {
"key": { "origin": "https://web.dev", "formFactor": "DESKTOP" },
"metrics": {
"largest_contentful_paint": {
"histogram": [
{ "start": 0, "end": 2500, "density": 0.8421 },
{ "start": 2500, "end": 4000, "density": 0.1213 },
{ "start": 4000, "density": 0.0366 }
],
"percentiles": { "p75": 1820 }
}
},
"collectionPeriod": {
"firstDate": { "year": 2026, "month": 3, "day": 30 },
"lastDate": { "year": 2026, "month": 4, "day": 26 }
}
}
}
解讀範本:上面這個 origin 的 p75 LCP = 1820 ms,落在第一個 bucket(< 2500 ms)算 Good。density 三個加起來大約是 1.0,代表 84% 的 page view 在 2.5 秒內看到主要內容,3.7% 落到 4 秒以上的 Poor 區。collectionPeriod 是 28 天滾動視窗,今天看跟下週看會差幾天,但不會差太多,這是 CrUX 的取樣節奏。
為什麼 Google 用 p75 不用平均值?因為效能資料分布有長尾,小部分使用者用的裝置很慢、網路很爛,平均值會被拉高很多。p75 抓的是「四分之三的使用者體驗到的速度」,比較接近真實感受,也比平均值穩定。我自己幫客戶看數據時習慣同時看 histogram 跟 p75,光看一個會漏掉風險集中在哪一段。
用 CrUX History API 看 6 個月趨勢,揪出回歸風險
CrUX History API 是 weekly snapshot 的時間序列,每筆資料代表一個 28 天的滾動視窗,最多回傳 25 週、約半年。端點長這樣:
curl "https://chromeuxreport.googleapis.com/v1/records:queryHistoryRecord?key=API_KEY" \
-H "Content-Type: application/json" \
--data '{
"origin": "https://web.dev",
"formFactor": "PHONE",
"metrics": ["largest_contentful_paint", "interaction_to_next_paint"]
}'
回傳的結構跟單次 API 類似,差別在 collectionPeriods 變成陣列,每個 metric 也會給你一個 25 個元素的 p75 陣列,跟 collectionPeriods 一一對應。最常見的監控用法是把這 25 筆塞進折線圖,當 p75 突然從 2.0s 跳到 3.5s,就知道某次發版引入了回歸。
實務上有個小坑:因為每筆 datapoint 是 28 天的滾動平均,當你在週一發版引入一個拖慢 LCP 的改動,CrUX History 上看到的影響不會在下一週就完整顯現。28 天視窗會稀釋掉前面 21 天的好成績,差不多要一個月之後 p75 才會穩定到新的「壞值」。發版回歸看 CrUX 太慢,平常還是要靠自家 RUM 或 PSI 跑一次。
如果你比較好奇單次跟歷史 API 的回傳差異,官方 History API 文件有貼完整範例,但對 CrUX 新手來說 queryRecord 是更好的入門點,趨勢監控可以等 dashboard 接好之後再來。
沒有 CrUX 資料?四個資格門檻 checklist
CrUX 不是每個網站都有資料,要過四個門檻:足夠的 Chrome 使用者樣本、可被公開搜尋(HSTS、indexed)、有 HTTPS、不被隱私政策排除。任何一條沒過,撈出來會收到 404 或 Chrome UX report data not found。
- 樣本量門檻:Chrome 沒公開數字,但實務觀察月流量在 5,000 PV 以下的小站幾乎都查不到。如果是新站、長尾站、員工內部頁面,就先別期待。
- HTTPS 與可索引:CrUX 只收公開可導航的頁面,內網、會員後台、被 robots noindex 的頁面通通不算。如果你的目標頁需要登入,永遠不會出現在 CrUX。
- 足夠的裝置/國家分布:如果你的流量集中在單一裝置或單一國家而樣本太少,CrUX 不會回傳該細分。多數小型 TW 站只能查到 origin level 而沒有 url level。
- 使用者隱私偏好:在 Chrome 設定關閉「Make searches and browsing better」的使用者不會被收進 CrUX,這個比例 Google 沒公開,但對小站影響更明顯。
如果四條全過還是抓不到,下一步通常不是繼續爭取 CrUX,而是改用 RUM。CrUX 與 RUM 的取樣差異說明把這個取捨講得很清楚:CrUX 取樣母體小、延遲長、但免維護;自家 RUM 取得百分百流量、延遲為零,但要花工程時間。我幫小型 TW 客戶站幾乎都直接跳過 CrUX,先把 GA4 的 web vitals event 接好,至少自己看得到數字。
CrUX Vis、PageSpeed Insights、BigQuery:什麼時候用哪個
CrUX Vis 是免登入 UI 工具,PageSpeed Insights 是 Lighthouse + CrUX 的合體頁,BigQuery 是 SQL 大規模分析入口。三個入口背後都是同一份 CrUX 資料集,差在介面跟解析自由度。
CrUX Vis 在 cruxvis.withgoogle.com,輸入 URL 就能看 6 個月折線圖、和裝置別比較,適合給不寫 code 的 PM 或主管看趨勢。資料就是 History API 的視覺化包裝,沒有額外的東西。如果你的需求只是「我想看走勢」,這個比寫 curl 快十倍。
PageSpeed Insights 把 CrUX 摘要塞在 Lighthouse 報告的最上面,但有個常被忽略的細節:PSI 顯示的 CrUX 是當下 28 天的快照,跟 Lighthouse 在你這台機器上跑出來的 lab data 是兩回事。如果兩邊數字差很多,多半是你個人網路或裝置條件跟 CrUX 母體差異大,不是 PSI 壞了。詳細的 lab 與 field 數字落差原因可以看 PSI Lab Data 與 Field Data 分數差距 這篇拆解。
BigQuery 的 chrome-ux-report 公開資料集是月表,命名是 chrome-ux-report.country_tw.YYYYMM(依國家分表),裡面每筆是 origin + form_factor 的 histogram 和 effective_connection_type。一個月台灣表大約 200-300 MB 範圍,用 SELECT * 會把整張表掃完,BigQuery 對一般帳戶第一個 1 TB 免費,所以只要 query 寫得不亂,每月成本通常壓得住,但如果你 SELECT * 跨國家跨年掃就會吃掉幾百 GB。
第一次用 BigQuery 撈 CrUX,從 BigQuery 上的 chrome-ux-report 公開資料集頁面進去,那邊有 schema 跟範例 query 可以複製。實務上會先在查詢編輯器看右下角的 estimated bytes processed,如果超過幾 GB 就把 SELECT * 換成只挑需要的欄位,BigQuery 是 columnar 儲存,少選欄位省的不只是錢還是速度。
為什麼同個 URL 在不同工具看到不同數字
同一個 URL 在 Lighthouse、PSI 的 CrUX 摘要、CrUX API、自家 RUM 看到不同數字,是因為這四個資料源的取樣母體不同。先理解差異在哪,下次跟同事吵「到底哪個才對」就有依據。
| 資料源 | 取樣母體 | 時間範圍 | 裝置條件 |
|---|---|---|---|
| Lighthouse (lab data) | 單次模擬,1 個 user | 當下這次跑 | 固定 Moto G Power + 模擬 4G |
| PSI 顯示的 CrUX 摘要 | 所有合格 Chrome 使用者 | 過去 28 天滾動 | 真實裝置混合 |
| CrUX API queryRecord | 同上 | 同上 | 可指定 PHONE/DESKTOP/TABLET |
| 自家 RUM (web-vitals.js) | 你自己埋點抓到的所有訪客 | 你自己定義的時間視窗 | 所有瀏覽器、所有裝置 |
母體差異會放大成數字差異。Lighthouse 是固定的中階手機加 4G 模擬,跑一次就是一個分數,跟你網站真實使用者的高階手機 + Wi-Fi 體驗差很多,所以常見「Lighthouse 70 分但 CrUX 顯示 Good」的狀況。CrUX 是 28 天滾動,回應慢,看不到剛剛 30 分鐘前的回歸;自家 RUM 看得到即時,但只看自己裝的網站,沒辦法跟競品比。
另外有個常被遺漏的點:CrUX 用 p75 而非 p50(中位數)或平均值,背後是 Chrome 團隊判斷「四分之三的使用者體驗」對 SEO 更有意義。RUM 工具預設給你的可能是 median 或 mean,看的時候要把指標切到 p75 才能跟 CrUX 對齊。我幫客戶 debug 數字差異,第一步永遠是看雙方是不是都用 p75,光這個就能解掉一半的爭議。
CrUX 數據怎麼搭配 GA4 與 Search Console 一起看
把 CrUX 接進日常監控有三條路徑:手動跑 PSI、用 CrUX API 自動化抓進 dashboard、直接看 Search Console 核心網站指標報告。三條路徑解決不同層級的需求,可以混著用。
路徑一是手動跑 PSI,最低工程成本。Search Console 的「核心網站指標」報告底下其實就是 CrUX 資料,每隔幾天會更新一次,按頁面分群顯示哪些 URL 落到 Poor。對於沒有自家 RUM 的小團隊,這條路就夠了,缺點是看不到分鐘級的變化,PSI 也不能做 alerting。
路徑二是 CrUX API 跑 cron job,把 p75 寫進 InfluxDB / Postgres,再接 Grafana 出圖。這條路適合有 SRE 文化的團隊,做 CI/CD 上線前後對比、每週寄 weekly digest 給工程主管。Quota 部分 CrUX API 一個專案每分鐘 150 次、每天大約幾千次,對自家網站數十條 origin 來說綽綽有餘,但要把競品也撈進來時要分時段跑。
路徑三是把 CrUX 跟自家 GA4 web-vitals event 並排比對,這個對 PM 很有用。GA4 用 web-vitals.js 自己埋點抓到所有 page view,CrUX 給的是 p75 對外公開的數字,當兩邊背離很多就要去看是不是某一群使用者(特定地區、特定裝置)在拖。完整的工程實踐脈絡可以回到 Core Web Vitals 完整指南,這篇從指標定義一路串到優化策略,把上下游一次補齊。
CrUX 資料多久更新一次?
CrUX API 跟 PSI 顯示的資料是「過去 28 天滾動視窗」,每天往前推一格,所以技術上每天都會微幅變動。CrUX History API 跟 BigQuery 月表則是每週、每月固定釋出。需要看趨勢用 History,需要看當下用 queryRecord。
為什麼我的網站在 PSI 看得到分數,CrUX 卻說沒資料?
PSI 一定會顯示分數,因為它至少會跑一次 Lighthouse 給你 lab data。沒 CrUX 通常是流量不夠(粗略門檻:月活躍 PV 要五位數以上)、頁面被 noindex、需要登入,或被歸到隱私豁免。先看 PSI 報告中段是不是顯示「This URL is not associated with...」,那行就是在告訴你 CrUX 沒收到你。
CrUX API 有 quota 嗎?要付費嗎?
免費,但有 quota:每個 GCP 專案預設每分鐘 150 次請求、每天大約 25,000 次,對單站監控來說綽綽有餘。如果做 SaaS 抓上千 origin,要分專案或申請提高配額。
CrUX 的 p75 是怎麼算的?為什麼不用平均值?
p75 是把所有 page view 的數值排序後取第 75 百分位,意思是「四分之三的使用者體驗到的速度比這個快」。Chrome 團隊選 p75 的理由:效能資料分布有長尾,平均值會被少數極慢的個案拉高,p75 比較穩定也比較貼近真實感受。
CrUX History API 和 BigQuery 月表的差別是什麼?
History API 給你每週一筆、最多 25 週的 p75 時間序列,回傳是 JSON、可即時查、適合自家 dashboard。BigQuery 月表給你每月一張、含完整 histogram 跟連線速度切片的 raw data,適合大規模 SQL 分析、跨國比較、或撈非 origin 的細分維度。前者是 monitoring,後者是 analytics。
CrUX 資料能不能拆出搜尋流量 vs 直接流量?
不行。CrUX 不收 referrer,不知道訪客是從 Google 搜尋來、從 LINE 點來、還是直接打網址來的。要拆流量來源就一定要靠自家 RUM 或 GA4 + web-vitals event 自己埋點抓。CrUX 只回答「整體 Chrome 使用者體驗到的速度」,不回答「哪一群使用者」。
CrUX Vis 和 PageSpeed Insights 的圖表為什麼不一樣?
CrUX Vis 顯示的是 History API 的 25 週時間序列折線圖,PSI 只顯示當下 28 天的單一快照數字加 histogram bar。CrUX Vis 看趨勢,PSI 看當下狀態,背後是同一份資料的不同視角。
用 BigQuery 查 CrUX 一個月大概要多少錢?
看你怎麼寫 SQL。台灣月表大約 200-300 MB,掃完全表幾乎免費(BigQuery 每帳戶每月前 1 TB 免費)。但如果你 SELECT * 跨多國家、跨多年份、又用 JOIN,動輒掃 100 GB 以上就要計費,BigQuery on-demand 大約 6.25 USD / TB。實務上把 query 限制在單一國家、單一月份、只 select 需要的欄位,幾乎都在免費額度內。