crux-api 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,18 +1,19 @@
1
1
  # crux-api
2
2
 
3
- > A [Chrome UX Report API](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference) wrapper that handles errors, retries, and provides types.
3
+ > A tiny [CrUX API](https://developer.chrome.com/docs/crux/api/) wrapper that supports record & history API, handles errors, and provides types.
4
4
 
5
- **Motivation**: [CrUX API](https://web.dev/chrome-ux-report-api/) is a fantastic tool to get RUM data without installing any script.
6
- While using the API in [Treo](https://treo.sh/), we discovered a few complex cases like API errors, rate limits, not found entries, a complicated multipart response from the batch API, URLs normalization, and TypeScript notations. We decided to build the `crux-api` library to makes it easier to work with the CrUX API.
5
+ **Motivation**: [CrUX API](https://developer.chrome.com/docs/crux/api/) is a fantastic tool to get RUM data without installing any script.
6
+ While using the API in [Treo](https://treo.sh/), we discovered a few complex cases like API errors, rate limits, not found entries, URLs normalization, and TypeScript notations. We decided to build the `crux-api` library to make working with the CrUX API easier.
7
7
 
8
8
  **Features**:
9
9
 
10
- - A tiny (450 bytes) wrapper for [Chrome UX Report API](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference);
11
- - TypeScript notations for [options and responses](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference/rest/v1/records/queryRecord);
10
+ - A tiny (500 bytes) wrapper for [Chrome UX Report API](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference);
11
+ - Supports both the [record](https://developer.chrome.com/docs/crux/api/) & [history](https://developer.chrome.com/docs/crux/history-api/) API;
12
+ - TypeScript notations for [options and responses](https://developer.chrome.com/docs/crux/api/#request-body);
12
13
  - Isomorphic: works in a browser and node.js;
13
14
  - Returns `null` for the `404 (CrUX data not found)` response;
14
15
  - Automatic retry when hits the API rate limits: `429 (Quota exceeded)`;
15
- - URL normalization helper to match the CrUX API index;
16
+ - URL normalization helper to check the CrUX API index;
16
17
 
17
18
  ## Usage
18
19
 
@@ -22,39 +23,23 @@ Install:
22
23
  npm install crux-api
23
24
  ```
24
25
 
25
- Fetch URL-level data for a various form factors and connections:
26
+ **Fetch URL-level data for a various form factors and connections**:
26
27
 
27
28
  ```js
28
29
  import { createQueryRecord } from 'crux-api'
29
30
  const queryRecord = createQueryRecord({ key: CRUX_API_KEY })
30
31
 
31
- const res1 = await queryRecord({ url: 'https://www.github.com/' }) // fetch all dimensions
32
- const res2 = await queryRecord({ url: 'https://www.github.com/explore', formFactor: 'DESKTOP' }) // fetch data for desktop devices
32
+ // fetch all dimensions
33
+ const jsonRecord = await queryRecord({ url: 'https://github.com/marketplace?type=actions', formFactor: 'DESKTOP' })
33
34
  ```
34
35
 
35
- Fetch origin-level data in node.js using [`node-fetch`](https://www.npmjs.com/package/node-fetch):
36
-
37
- ```js
38
- import { createQueryRecord } from 'crux-api'
39
- import nodeFetch from 'node-fetch'
40
- const queryRecord = createQueryRecord({ key: process.env.CRUX_API_KEY, fetch: nodeFetch })
41
-
42
- const res1 = await queryRecord({ origin: 'https://github.com' })
43
- const res2 = await queryRecord({
44
- origin: 'https://www.github.com/marketplace?type=actions',
45
- formFactor: 'DESKTOP',
46
- effectiveConnectionType: '4G',
47
- })
48
- ```
49
-
50
- Result is `null` or an `object` with [queryRecord response body](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference/rest/v1/records/queryRecord#response-body), ex:
36
+ The `jsonRecord` is `null` or an `object` with [queryRecord response body](https://developer.chrome.com/docs/crux/api/#response-body), ex:
51
37
 
52
38
  ```json
53
39
  {
54
40
  "record": {
55
41
  "key": {
56
42
  "formFactor": "DESKTOP",
57
- "effectiveConnectionType": "4G",
58
43
  "url": "https://github.com/marketplace"
59
44
  },
60
45
  "metrics": {
@@ -71,6 +56,8 @@ Result is `null` or an `object` with [queryRecord response body](https://develop
71
56
  "cumulative_layout_shift": { ... },
72
57
  "first_input_delay": { ... },
73
58
  "largest_contentful_paint": { ... },
59
+ "interaction_to_next_paint": { ... },
60
+ "experimental_time_to_first_byte": { ... },
74
61
  }
75
62
  },
76
63
  "urlNormalizationDetails": {
@@ -80,6 +67,55 @@ Result is `null` or an `object` with [queryRecord response body](https://develop
80
67
  }
81
68
  ```
82
69
 
70
+ **Fetch historic data for a URL**:
71
+
72
+ ```js
73
+ import { createQueryRecord } from 'crux-api'
74
+ const queryRecord = createQueryHistoryRecord({ key: CRUX_API_KEY })
75
+
76
+ const jsonHistory = await queryRecord({ url: 'https://www.github.com/' }) // fetch ALL_FORM_FACTORS
77
+ ```
78
+
79
+ The `jsonHistory` is `null` or an `object` with [queryRecord response body](https://developer.chrome.com/docs/crux/history-api/#response-body), ex:
80
+
81
+ ```json
82
+ {
83
+ "record": {
84
+ "key": {
85
+ "url": "https://github.com/"
86
+ },
87
+ "metrics": {
88
+ "cumulative_layout_shift": {
89
+ "histogramTimeseries": [
90
+ {
91
+ "start": "0.00",
92
+ "end": "0.10",
93
+ "densities": [0.716522216796875, 0.672149658203125, ...]
94
+ },
95
+ {
96
+ "start": "0.10",
97
+ "end": "0.25",
98
+ "densities": [0.244537353515625, 0.246917724609375, ...]
99
+ },
100
+ {
101
+ "start": "0.25",
102
+ "densities": [0.0389404296875, 0.0809326171875, ...]
103
+ }
104
+ ],
105
+ "percentilesTimeseries": {
106
+ "p75s": ["0.10", "0.12", ...]
107
+ }
108
+ },
109
+ "experimental_time_to_first_byte": { ... },
110
+ "first_contentful_paint": { ... },
111
+ "first_input_delay": { ... },
112
+ "interaction_to_next_paint": { ... },
113
+ "largest_contentful_paint": { ... }
114
+ }
115
+ }
116
+ }
117
+ ```
118
+
83
119
  ## API
84
120
 
85
121
  ### createQueryRecord(createOptions)
@@ -91,13 +127,13 @@ Returns a `queryRecord` function.
91
127
 
92
128
  #### queryRecord(queryOptions)
93
129
 
94
- Fetches CrUX API using [`queryRecord options`](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference/rest/v1/records/queryRecord):
130
+ Fetches CrUX API using [`queryRecord options`](https://developer.chrome.com/docs/crux/api/):
95
131
 
96
132
  - _queryOptions.url_ or _queryOptions.origin_ (**required**) – the main identifier for a record lookup;
97
133
  - _queryOptions.formFactor_ (optional, defaults to all form factors) - the form factor dimension: `PHONE` | `DESKTOP` | `TABLET`;
98
134
  - _queryOptions.effectiveConnectionType_ (optional, defaults to all connections) - the effective network class: `4G` | `3G` | `2G` | `slow-2G` | `offline`.
99
135
 
100
- Returns a Promise with a raw [`queryRecord` response](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference/rest/v1/records/queryRecord#response-body) or `null` when the data is not found.
136
+ Returns a Promise with a raw [`queryRecord` response](https://developer.chrome.com/docs/crux/api/#response-body) or `null` when the data is not found.
101
137
 
102
138
  ```js
103
139
  import { createQueryRecord } from 'crux-api'
@@ -112,6 +148,19 @@ const res = await queryRecord({
112
148
  // res -> URL-level data for https://github.com/marketplace
113
149
  ```
114
150
 
151
+ ### createQueryHistoryRecord(historyOptions)
152
+
153
+ Returns a function that fetches [CrUX History API using [`queryHistoryRecord options`](https://developer.chrome.com/docs/crux/history-api/#http-request):
154
+
155
+ ```js
156
+ import { createQueryHistoryRecord } from 'crux-api'
157
+
158
+ const queryHistory = createQueryHistoryRecord({ key: process.env.CRUX_API_KEY })
159
+ const res = await queryHistory({
160
+ url: 'https://www.github.com/',
161
+ })
162
+ ```
163
+
115
164
  ### normalizeUrl(url)
116
165
 
117
166
  Normalize a URL to match the CrUX API internal index.
@@ -132,12 +181,607 @@ For `400` and `5xx` it throws a relevant error.
132
181
  Below are all known responses of [Chrome UX Report API](https://developers.google.com/web/tools/chrome-user-experience-report/api/reference) for easier debugging and development (The API documentation is vague about errors, [please, submit an issue](https://github.com/treosh/crux-api/issues), if you know other responses).
133
182
 
134
183
  <details>
135
- <summary>✅ 200: URL-level data</summary><br>
184
+ <summary>✅ 200: URL-level CrUX History API data</summary><br>
185
+
186
+ ```bash
187
+ curl -d url='https://github.com/' \
188
+ -d formFactor=DESKTOP \
189
+ 'https://chromeuxreport.googleapis.com/v1/records:queryHistoryRecord?key=CRUX_API_KEY'
190
+ ```
191
+
192
+ ```json
193
+ {
194
+ "record": {
195
+ "key": {
196
+ "formFactor": "DESKTOP",
197
+ "url": "https://github.com/"
198
+ },
199
+ "metrics": {
200
+ "cumulative_layout_shift": {
201
+ "histogramTimeseries": [
202
+ {
203
+ "start": "0.00",
204
+ "end": "0.10",
205
+ "densities": [
206
+ 0.726043701171875, 0.676971435546875, 0.638519287109375, 0.629058837890625, 0.622161865234375,
207
+ 0.656158447265625, 0.688262939453125, 0.73272705078125, 0.791351318359375, 0.845489501953125,
208
+ 0.897674560546875, 0.916046142578125, 0.91455078125, 0.91363525390625, 0.913543701171875,
209
+ 0.915008544921875, 0.9166259765625, 0.9210205078125, 0.929107666015625, 0.936553955078125,
210
+ 0.93804931640625, 0.925628662109375, 0.913299560546875, 0.9024658203125, 0.903533935546875
211
+ ]
212
+ },
213
+ {
214
+ "start": "0.10",
215
+ "end": "0.25",
216
+ "densities": [
217
+ 0.2373046875, 0.240753173828125, 0.224029541015625, 0.190032958984375, 0.1575927734375, 0.123931884765625,
218
+ 0.10748291015625, 0.098846435546875, 0.087677001953125, 0.07757568359375, 0.069122314453125,
219
+ 0.065460205078125, 0.064697265625, 0.06402587890625, 0.06298828125, 0.061614990234375, 0.0601806640625,
220
+ 0.05560302734375, 0.048614501953125, 0.041778564453125, 0.041229248046875, 0.05340576171875,
221
+ 0.0660400390625, 0.07568359375, 0.07342529296875
222
+ ]
223
+ },
224
+ {
225
+ "start": "0.25",
226
+ "densities": [
227
+ 0.036651611328125, 0.082275390625, 0.137451171875, 0.180908203125, 0.220245361328125, 0.21990966796875,
228
+ 0.204254150390625, 0.168426513671875, 0.1209716796875, 0.076934814453125, 0.033203125, 0.01849365234375,
229
+ 0.020751953125, 0.0223388671875, 0.023468017578125, 0.02337646484375, 0.023193359375, 0.02337646484375,
230
+ 0.02227783203125, 0.02166748046875, 0.020721435546875, 0.020965576171875, 0.020660400390625,
231
+ 0.0218505859375, 0.023040771484375
232
+ ]
233
+ }
234
+ ],
235
+ "percentilesTimeseries": {
236
+ "p75s": [
237
+ "0.10",
238
+ "0.11",
239
+ "0.12",
240
+ "0.14",
241
+ "0.18",
242
+ "0.17",
243
+ "0.14",
244
+ "0.10",
245
+ "0.08",
246
+ "0.07",
247
+ "0.06",
248
+ "0.06",
249
+ "0.06",
250
+ "0.06",
251
+ "0.06",
252
+ "0.06",
253
+ "0.06",
254
+ "0.06",
255
+ "0.05",
256
+ "0.05",
257
+ "0.04",
258
+ "0.05",
259
+ "0.05",
260
+ "0.05",
261
+ "0.05"
262
+ ]
263
+ }
264
+ },
265
+ "experimental_time_to_first_byte": {
266
+ "histogramTimeseries": [
267
+ {
268
+ "start": 0,
269
+ "end": 800,
270
+ "densities": [
271
+ 0.779144287109375, 0.780303955078125, 0.777435302734375, 0.77899169921875, 0.780487060546875,
272
+ 0.779144287109375, 0.77862548828125, 0.776763916015625, 0.774810791015625, 0.76995849609375,
273
+ 0.765777587890625, 0.75335693359375, 0.741180419921875, 0.73614501953125, 0.732025146484375,
274
+ 0.7298583984375, 0.7265625, 0.72662353515625, 0.724853515625, 0.72650146484375, 0.7236328125,
275
+ 0.718994140625, 0.717437744140625, 0.71881103515625, 0.721832275390625
276
+ ]
277
+ },
278
+ {
279
+ "start": 800,
280
+ "end": 1800,
281
+ "densities": [
282
+ 0.1845703125, 0.184783935546875, 0.187591552734375, 0.186492919921875, 0.186920166015625,
283
+ 0.189056396484375, 0.190155029296875, 0.193328857421875, 0.1947021484375, 0.19903564453125,
284
+ 0.202911376953125, 0.21380615234375, 0.22515869140625, 0.22967529296875, 0.232208251953125,
285
+ 0.23468017578125, 0.23553466796875, 0.236907958984375, 0.237640380859375, 0.2371826171875,
286
+ 0.23992919921875, 0.24432373046875, 0.245819091796875, 0.24505615234375, 0.242095947265625
287
+ ]
288
+ },
289
+ {
290
+ "start": 1800,
291
+ "densities": [
292
+ 0.036285400390625, 0.034912109375, 0.03497314453125, 0.034515380859375, 0.0325927734375, 0.03179931640625,
293
+ 0.031219482421875, 0.0299072265625, 0.030487060546875, 0.031005859375, 0.03131103515625, 0.0328369140625,
294
+ 0.033660888671875, 0.0341796875, 0.0357666015625, 0.03546142578125, 0.03790283203125, 0.036468505859375,
295
+ 0.037506103515625, 0.03631591796875, 0.03643798828125, 0.03668212890625, 0.0367431640625, 0.0361328125,
296
+ 0.03607177734375
297
+ ]
298
+ }
299
+ ],
300
+ "percentilesTimeseries": {
301
+ "p75s": [
302
+ 748, 749, 752, 752, 751, 752, 755, 757, 761, 768, 778, 796, 814, 821, 826, 832, 832, 834, 836, 836, 838,
303
+ 846, 847, 846, 841
304
+ ]
305
+ }
306
+ },
307
+ "first_contentful_paint": {
308
+ "histogramTimeseries": [
309
+ {
310
+ "start": 0,
311
+ "end": 1800,
312
+ "densities": [
313
+ 0.88543701171875, 0.88568115234375, 0.886962890625, 0.889556884765625, 0.8934326171875, 0.89837646484375,
314
+ 0.90142822265625, 0.903594970703125, 0.900787353515625, 0.899627685546875, 0.894317626953125,
315
+ 0.8936767578125, 0.89227294921875, 0.89227294921875, 0.8905029296875, 0.891815185546875, 0.88812255859375,
316
+ 0.88897705078125, 0.888946533203125, 0.888458251953125, 0.889923095703125, 0.88800048828125,
317
+ 0.88433837890625, 0.88311767578125, 0.880706787109375
318
+ ]
319
+ },
320
+ {
321
+ "start": 1800,
322
+ "end": 3000,
323
+ "densities": [
324
+ 0.07373046875, 0.07440185546875, 0.072662353515625, 0.0693359375, 0.0662841796875, 0.063446044921875,
325
+ 0.061248779296875, 0.06024169921875, 0.061920166015625, 0.06378173828125, 0.06536865234375,
326
+ 0.066314697265625, 0.0675048828125, 0.066741943359375, 0.06787109375, 0.0675048828125, 0.0699462890625,
327
+ 0.06915283203125, 0.068267822265625, 0.06878662109375, 0.068267822265625, 0.070343017578125,
328
+ 0.072509765625, 0.072418212890625, 0.073883056640625
329
+ ]
330
+ },
331
+ {
332
+ "start": 3000,
333
+ "densities": [
334
+ 0.04083251953125, 0.0399169921875, 0.040374755859375, 0.041107177734375, 0.040283203125,
335
+ 0.038177490234375, 0.037322998046875, 0.036163330078125, 0.03729248046875, 0.036590576171875,
336
+ 0.040313720703125, 0.040008544921875, 0.04022216796875, 0.040985107421875, 0.0416259765625,
337
+ 0.040679931640625, 0.04193115234375, 0.0418701171875, 0.04278564453125, 0.042755126953125,
338
+ 0.04180908203125, 0.041656494140625, 0.04315185546875, 0.044464111328125, 0.04541015625
339
+ ]
340
+ }
341
+ ],
342
+ "percentilesTimeseries": {
343
+ "p75s": [
344
+ 1221, 1216, 1219, 1205, 1186, 1173, 1158, 1157, 1165, 1175, 1190, 1204, 1214, 1217, 1222, 1227, 1231, 1237,
345
+ 1237, 1237, 1236, 1250, 1263, 1272, 1276
346
+ ]
347
+ }
348
+ },
349
+ "first_input_delay": {
350
+ "histogramTimeseries": [
351
+ {
352
+ "start": 0,
353
+ "end": 100,
354
+ "densities": [
355
+ 0.970855712890625, 0.971649169921875, 0.97064208984375, 0.969085693359375, 0.96905517578125,
356
+ 0.968017578125, 0.969146728515625, 0.96868896484375, 0.9720458984375, 0.971710205078125, 0.9720458984375,
357
+ 0.97308349609375, 0.974609375, 0.9749755859375, 0.974090576171875, 0.97412109375, 0.9752197265625,
358
+ 0.97528076171875, 0.9747314453125, 0.973236083984375, 0.973846435546875, 0.97296142578125,
359
+ 0.974884033203125, 0.97357177734375, 0.975128173828125
360
+ ]
361
+ },
362
+ {
363
+ "start": 100,
364
+ "end": 300,
365
+ "densities": [
366
+ 0.01763916015625, 0.01641845703125, 0.017730712890625, 0.0181884765625, 0.018218994140625,
367
+ 0.019622802734375, 0.01849365234375, 0.019256591796875, 0.0172119140625, 0.017608642578125,
368
+ 0.017059326171875, 0.016876220703125, 0.015350341796875, 0.014984130859375, 0.0159912109375,
369
+ 0.016021728515625, 0.014495849609375, 0.0145263671875, 0.014739990234375, 0.0159912109375,
370
+ 0.01568603515625, 0.016204833984375, 0.014739990234375, 0.01617431640625, 0.01416015625
371
+ ]
372
+ },
373
+ {
374
+ "start": 300,
375
+ "densities": [
376
+ 0.011505126953125, 0.011932373046875, 0.011627197265625, 0.012725830078125, 0.012725830078125,
377
+ 0.012359619140625, 0.012359619140625, 0.012054443359375, 0.0107421875, 0.01068115234375,
378
+ 0.010894775390625, 0.010040283203125, 0.010040283203125, 0.010040283203125, 0.009918212890625,
379
+ 0.009857177734375, 0.010284423828125, 0.01019287109375, 0.010528564453125, 0.010772705078125,
380
+ 0.010467529296875, 0.010833740234375, 0.0103759765625, 0.01025390625, 0.010711669921875
381
+ ]
382
+ }
383
+ ],
384
+ "percentilesTimeseries": {
385
+ "p75s": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
386
+ }
387
+ },
388
+ "interaction_to_next_paint": {
389
+ "histogramTimeseries": [
390
+ {
391
+ "start": 0,
392
+ "end": 200,
393
+ "densities": [
394
+ 0.9437255859375, 0.944244384765625, 0.94207763671875, 0.938720703125, 0.936737060546875,
395
+ 0.936126708984375, 0.93768310546875, 0.93988037109375, 0.94134521484375, 0.9393310546875, 0.9384765625,
396
+ 0.939208984375, 0.937744140625, 0.9365234375, 0.937286376953125, 0.937896728515625, 0.937591552734375,
397
+ 0.93682861328125, 0.9373779296875, 0.93505859375, 0.9368896484375, 0.9373779296875, 0.937255859375,
398
+ 0.938629150390625, 0.940155029296875
399
+ ]
400
+ },
401
+ {
402
+ "start": 200,
403
+ "end": 500,
404
+ "densities": [
405
+ 0.03204345703125, 0.032135009765625, 0.034271240234375, 0.0360107421875, 0.0382080078125, 0.0384521484375,
406
+ 0.038360595703125, 0.037994384765625, 0.036376953125, 0.037841796875, 0.038848876953125, 0.03875732421875,
407
+ 0.039947509765625, 0.04107666015625, 0.040435791015625, 0.039337158203125, 0.039947509765625,
408
+ 0.040313720703125, 0.04034423828125, 0.04168701171875, 0.0406494140625, 0.03924560546875,
409
+ 0.039581298828125, 0.039459228515625, 0.03814697265625
410
+ ]
411
+ },
412
+ {
413
+ "start": 500,
414
+ "densities": [
415
+ 0.02423095703125, 0.02362060546875, 0.023651123046875, 0.0252685546875, 0.025054931640625,
416
+ 0.025421142578125, 0.023956298828125, 0.022125244140625, 0.02227783203125, 0.0228271484375,
417
+ 0.022674560546875, 0.02203369140625, 0.022308349609375, 0.02239990234375, 0.02227783203125,
418
+ 0.02276611328125, 0.0224609375, 0.022857666015625, 0.02227783203125, 0.02325439453125, 0.0224609375,
419
+ 0.02337646484375, 0.023162841796875, 0.02191162109375, 0.021697998046875
420
+ ]
421
+ }
422
+ ],
423
+ "percentilesTimeseries": {
424
+ "p75s": [61, 62, 63, 64, 65, 66, 66, 66, 66, 67, 68, 70, 72, 73, 73, 72, 72, 73, 72, 71, 70, 70, 69, 69, 69]
425
+ }
426
+ },
427
+ "largest_contentful_paint": {
428
+ "histogramTimeseries": [
429
+ {
430
+ "start": 0,
431
+ "end": 2500,
432
+ "densities": [
433
+ 0.86895751953125, 0.850921630859375, 0.834320068359375, 0.818145751953125, 0.802490234375,
434
+ 0.796417236328125, 0.79620361328125, 0.809417724609375, 0.830078125, 0.850067138671875, 0.87017822265625,
435
+ 0.87786865234375, 0.87628173828125, 0.875823974609375, 0.875335693359375, 0.867889404296875,
436
+ 0.869781494140625, 0.87115478515625, 0.869476318359375, 0.874481201171875, 0.877227783203125,
437
+ 0.884185791015625, 0.890472412109375, 0.895751953125, 0.896820068359375
438
+ ]
439
+ },
440
+ {
441
+ "start": 2500,
442
+ "end": 4000,
443
+ "densities": [
444
+ 0.08221435546875, 0.09649658203125, 0.10797119140625, 0.11907958984375, 0.130035400390625,
445
+ 0.1356201171875, 0.135101318359375, 0.12530517578125, 0.110565185546875, 0.095550537109375,
446
+ 0.07904052734375, 0.072845458984375, 0.074127197265625, 0.0743408203125, 0.07452392578125,
447
+ 0.080596923828125, 0.07769775390625, 0.078460693359375, 0.0782470703125, 0.074798583984375,
448
+ 0.07415771484375, 0.0692138671875, 0.06475830078125, 0.0615234375, 0.0595703125
449
+ ]
450
+ },
451
+ {
452
+ "start": 4000,
453
+ "densities": [
454
+ 0.048828125, 0.052581787109375, 0.057708740234375, 0.062774658203125, 0.067474365234375,
455
+ 0.067962646484375, 0.068695068359375, 0.065277099609375, 0.059356689453125, 0.05438232421875, 0.05078125,
456
+ 0.049285888671875, 0.049591064453125, 0.049835205078125, 0.050140380859375, 0.051513671875,
457
+ 0.052520751953125, 0.050384521484375, 0.052276611328125, 0.05072021484375, 0.048614501953125,
458
+ 0.046600341796875, 0.044769287109375, 0.042724609375, 0.043609619140625
459
+ ]
460
+ }
461
+ ],
462
+ "percentilesTimeseries": {
463
+ "p75s": [
464
+ 1815, 1953, 2056, 2148, 2236, 2271, 2273, 2200, 2068, 1918, 1757, 1695, 1715, 1719, 1726, 1772, 1760, 1760,
465
+ 1762, 1726, 1701, 1657, 1618, 1579, 1556
466
+ ]
467
+ }
468
+ }
469
+ },
470
+ "collectionPeriods": [
471
+ {
472
+ "firstDate": {
473
+ "year": 2023,
474
+ "month": 3,
475
+ "day": 26
476
+ },
477
+ "lastDate": {
478
+ "year": 2023,
479
+ "month": 4,
480
+ "day": 22
481
+ }
482
+ },
483
+ {
484
+ "firstDate": {
485
+ "year": 2023,
486
+ "month": 4,
487
+ "day": 2
488
+ },
489
+ "lastDate": {
490
+ "year": 2023,
491
+ "month": 4,
492
+ "day": 29
493
+ }
494
+ },
495
+ {
496
+ "firstDate": {
497
+ "year": 2023,
498
+ "month": 4,
499
+ "day": 9
500
+ },
501
+ "lastDate": {
502
+ "year": 2023,
503
+ "month": 5,
504
+ "day": 6
505
+ }
506
+ },
507
+ {
508
+ "firstDate": {
509
+ "year": 2023,
510
+ "month": 4,
511
+ "day": 16
512
+ },
513
+ "lastDate": {
514
+ "year": 2023,
515
+ "month": 5,
516
+ "day": 13
517
+ }
518
+ },
519
+ {
520
+ "firstDate": {
521
+ "year": 2023,
522
+ "month": 4,
523
+ "day": 23
524
+ },
525
+ "lastDate": {
526
+ "year": 2023,
527
+ "month": 5,
528
+ "day": 20
529
+ }
530
+ },
531
+ {
532
+ "firstDate": {
533
+ "year": 2023,
534
+ "month": 4,
535
+ "day": 30
536
+ },
537
+ "lastDate": {
538
+ "year": 2023,
539
+ "month": 5,
540
+ "day": 27
541
+ }
542
+ },
543
+ {
544
+ "firstDate": {
545
+ "year": 2023,
546
+ "month": 5,
547
+ "day": 7
548
+ },
549
+ "lastDate": {
550
+ "year": 2023,
551
+ "month": 6,
552
+ "day": 3
553
+ }
554
+ },
555
+ {
556
+ "firstDate": {
557
+ "year": 2023,
558
+ "month": 5,
559
+ "day": 14
560
+ },
561
+ "lastDate": {
562
+ "year": 2023,
563
+ "month": 6,
564
+ "day": 10
565
+ }
566
+ },
567
+ {
568
+ "firstDate": {
569
+ "year": 2023,
570
+ "month": 5,
571
+ "day": 21
572
+ },
573
+ "lastDate": {
574
+ "year": 2023,
575
+ "month": 6,
576
+ "day": 17
577
+ }
578
+ },
579
+ {
580
+ "firstDate": {
581
+ "year": 2023,
582
+ "month": 5,
583
+ "day": 28
584
+ },
585
+ "lastDate": {
586
+ "year": 2023,
587
+ "month": 6,
588
+ "day": 24
589
+ }
590
+ },
591
+ {
592
+ "firstDate": {
593
+ "year": 2023,
594
+ "month": 6,
595
+ "day": 4
596
+ },
597
+ "lastDate": {
598
+ "year": 2023,
599
+ "month": 7,
600
+ "day": 1
601
+ }
602
+ },
603
+ {
604
+ "firstDate": {
605
+ "year": 2023,
606
+ "month": 6,
607
+ "day": 11
608
+ },
609
+ "lastDate": {
610
+ "year": 2023,
611
+ "month": 7,
612
+ "day": 8
613
+ }
614
+ },
615
+ {
616
+ "firstDate": {
617
+ "year": 2023,
618
+ "month": 6,
619
+ "day": 18
620
+ },
621
+ "lastDate": {
622
+ "year": 2023,
623
+ "month": 7,
624
+ "day": 15
625
+ }
626
+ },
627
+ {
628
+ "firstDate": {
629
+ "year": 2023,
630
+ "month": 6,
631
+ "day": 25
632
+ },
633
+ "lastDate": {
634
+ "year": 2023,
635
+ "month": 7,
636
+ "day": 22
637
+ }
638
+ },
639
+ {
640
+ "firstDate": {
641
+ "year": 2023,
642
+ "month": 7,
643
+ "day": 2
644
+ },
645
+ "lastDate": {
646
+ "year": 2023,
647
+ "month": 7,
648
+ "day": 29
649
+ }
650
+ },
651
+ {
652
+ "firstDate": {
653
+ "year": 2023,
654
+ "month": 7,
655
+ "day": 9
656
+ },
657
+ "lastDate": {
658
+ "year": 2023,
659
+ "month": 8,
660
+ "day": 5
661
+ }
662
+ },
663
+ {
664
+ "firstDate": {
665
+ "year": 2023,
666
+ "month": 7,
667
+ "day": 16
668
+ },
669
+ "lastDate": {
670
+ "year": 2023,
671
+ "month": 8,
672
+ "day": 12
673
+ }
674
+ },
675
+ {
676
+ "firstDate": {
677
+ "year": 2023,
678
+ "month": 7,
679
+ "day": 23
680
+ },
681
+ "lastDate": {
682
+ "year": 2023,
683
+ "month": 8,
684
+ "day": 19
685
+ }
686
+ },
687
+ {
688
+ "firstDate": {
689
+ "year": 2023,
690
+ "month": 7,
691
+ "day": 30
692
+ },
693
+ "lastDate": {
694
+ "year": 2023,
695
+ "month": 8,
696
+ "day": 26
697
+ }
698
+ },
699
+ {
700
+ "firstDate": {
701
+ "year": 2023,
702
+ "month": 8,
703
+ "day": 6
704
+ },
705
+ "lastDate": {
706
+ "year": 2023,
707
+ "month": 9,
708
+ "day": 2
709
+ }
710
+ },
711
+ {
712
+ "firstDate": {
713
+ "year": 2023,
714
+ "month": 8,
715
+ "day": 13
716
+ },
717
+ "lastDate": {
718
+ "year": 2023,
719
+ "month": 9,
720
+ "day": 9
721
+ }
722
+ },
723
+ {
724
+ "firstDate": {
725
+ "year": 2023,
726
+ "month": 8,
727
+ "day": 20
728
+ },
729
+ "lastDate": {
730
+ "year": 2023,
731
+ "month": 9,
732
+ "day": 16
733
+ }
734
+ },
735
+ {
736
+ "firstDate": {
737
+ "year": 2023,
738
+ "month": 8,
739
+ "day": 27
740
+ },
741
+ "lastDate": {
742
+ "year": 2023,
743
+ "month": 9,
744
+ "day": 23
745
+ }
746
+ },
747
+ {
748
+ "firstDate": {
749
+ "year": 2023,
750
+ "month": 9,
751
+ "day": 3
752
+ },
753
+ "lastDate": {
754
+ "year": 2023,
755
+ "month": 9,
756
+ "day": 30
757
+ }
758
+ },
759
+ {
760
+ "firstDate": {
761
+ "year": 2023,
762
+ "month": 9,
763
+ "day": 10
764
+ },
765
+ "lastDate": {
766
+ "year": 2023,
767
+ "month": 10,
768
+ "day": 7
769
+ }
770
+ }
771
+ ]
772
+ }
773
+ }
774
+ ```
775
+
776
+ </details>
777
+
778
+ <details>
779
+ <summary>✅ 200: URL-level CrUX API data</summary><br>
136
780
 
137
781
  ```bash
138
782
  curl -d url='https://github.com/marketplace?type=actions' \
139
783
  -d effectiveConnectionType=4G \
140
- -d formFactor=PHONE \
784
+ -d formFactor=DESKTOP \
141
785
  'https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=CRUX_API_KEY'
142
786
  ```
143
787
 
@@ -145,7 +789,7 @@ curl -d url='https://github.com/marketplace?type=actions' \
145
789
  {
146
790
  "record": {
147
791
  "key": {
148
- "formFactor": "PHONE",
792
+ "formFactor": "DESKTOP",
149
793
  "effectiveConnectionType": "4G",
150
794
  "url": "https://github.com/marketplace"
151
795
  },
@@ -155,41 +799,62 @@ curl -d url='https://github.com/marketplace?type=actions' \
155
799
  {
156
800
  "start": "0.00",
157
801
  "end": "0.10",
158
- "density": 0.74598930481283388
802
+ "density": 0.9430604982206409
159
803
  },
160
804
  {
161
805
  "start": "0.10",
162
806
  "end": "0.25",
163
- "density": 0.17112299465240635
807
+ "density": 0.020804817957842878
164
808
  },
165
809
  {
166
810
  "start": "0.25",
167
- "density": 0.082887700534759287
811
+ "density": 0.03613468382151657
812
+ }
813
+ ],
814
+ "percentiles": {
815
+ "p75": "0.02"
816
+ }
817
+ },
818
+ "experimental_time_to_first_byte": {
819
+ "histogram": [
820
+ {
821
+ "start": 0,
822
+ "end": 800,
823
+ "density": 0.9393059587999442
824
+ },
825
+ {
826
+ "start": 800,
827
+ "end": 1800,
828
+ "density": 0.05378128024332917
829
+ },
830
+ {
831
+ "start": 1800,
832
+ "density": 0.006912760956726073
168
833
  }
169
834
  ],
170
835
  "percentiles": {
171
- "p75": "0.11"
836
+ "p75": 550
172
837
  }
173
838
  },
174
839
  "first_contentful_paint": {
175
840
  "histogram": [
176
841
  {
177
842
  "start": 0,
178
- "end": 1000,
179
- "density": 0.454180602006688
843
+ "end": 1800,
844
+ "density": 0.9731800766283532
180
845
  },
181
846
  {
182
- "start": 1000,
847
+ "start": 1800,
183
848
  "end": 3000,
184
- "density": 0.52575250836120291
849
+ "density": 0.017651888341543534
185
850
  },
186
851
  {
187
852
  "start": 3000,
188
- "density": 0.020066889632107024
853
+ "density": 0.009168035030104028
189
854
  }
190
855
  ],
191
856
  "percentiles": {
192
- "p75": 1365
857
+ "p75": 809
193
858
  }
194
859
  },
195
860
  "first_input_delay": {
@@ -197,20 +862,41 @@ curl -d url='https://github.com/marketplace?type=actions' \
197
862
  {
198
863
  "start": 0,
199
864
  "end": 100,
200
- "density": 0.812922614575508
865
+ "density": 0.9936164307521526
201
866
  },
202
867
  {
203
868
  "start": 100,
204
869
  "end": 300,
205
- "density": 0.1750563486100678
870
+ "density": 0.004579517069109083
206
871
  },
207
872
  {
208
873
  "start": 300,
209
- "density": 0.012021036814425257
874
+ "density": 0.0018040521787399426
875
+ }
876
+ ],
877
+ "percentiles": {
878
+ "p75": 3
879
+ }
880
+ },
881
+ "interaction_to_next_paint": {
882
+ "histogram": [
883
+ {
884
+ "start": 0,
885
+ "end": 200,
886
+ "density": 0.9759848893685868
887
+ },
888
+ {
889
+ "start": 200,
890
+ "end": 500,
891
+ "density": 0.014301133297355571
892
+ },
893
+ {
894
+ "start": 500,
895
+ "density": 0.009713977334052826
210
896
  }
211
897
  ],
212
898
  "percentiles": {
213
- "p75": 38
899
+ "p75": 50
214
900
  }
215
901
  },
216
902
  "largest_contentful_paint": {
@@ -218,22 +904,34 @@ curl -d url='https://github.com/marketplace?type=actions' \
218
904
  {
219
905
  "start": 0,
220
906
  "end": 2500,
221
- "density": 0.95027247956403227
907
+ "density": 0.9798854493386074
222
908
  },
223
909
  {
224
910
  "start": 2500,
225
911
  "end": 4000,
226
- "density": 0.039509536784741124
912
+ "density": 0.012886949406791222
227
913
  },
228
914
  {
229
915
  "start": 4000,
230
- "density": 0.010217983651226175
916
+ "density": 0.007227601254602516
231
917
  }
232
918
  ],
233
919
  "percentiles": {
234
- "p75": 1583
920
+ "p75": 895
235
921
  }
236
922
  }
923
+ },
924
+ "collectionPeriod": {
925
+ "firstDate": {
926
+ "year": 2023,
927
+ "month": 9,
928
+ "day": 15
929
+ },
930
+ "lastDate": {
931
+ "year": 2023,
932
+ "month": 10,
933
+ "day": 12
934
+ }
237
935
  }
238
936
  },
239
937
  "urlNormalizationDetails": {
@@ -246,11 +944,11 @@ curl -d url='https://github.com/marketplace?type=actions' \
246
944
  </details>
247
945
 
248
946
  <details>
249
- <summary>✅ 200: Origin-level data</summary><br>
947
+ <summary>✅ 200: Origin-level CrUX API data</summary><br>
250
948
 
251
949
  ```bash
252
950
  curl -d origin='https://github.com' \
253
- -d formFactor=DESKTOP \
951
+ -d formFactor=PHONE \
254
952
  'https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=CRUX_API_KEY'
255
953
  ```
256
954
 
@@ -258,7 +956,7 @@ curl -d origin='https://github.com' \
258
956
  {
259
957
  "record": {
260
958
  "key": {
261
- "formFactor": "DESKTOP",
959
+ "formFactor": "PHONE",
262
960
  "origin": "https://github.com"
263
961
  },
264
962
  "metrics": {
@@ -267,20 +965,41 @@ curl -d origin='https://github.com' \
267
965
  {
268
966
  "start": 0,
269
967
  "end": 100,
270
- "density": 0.99445638646905821
968
+ "density": 0.9498680738786286
271
969
  },
272
970
  {
273
971
  "start": 100,
274
972
  "end": 300,
275
- "density": 0.004072858920692389
973
+ "density": 0.03430079155672826
276
974
  },
277
975
  {
278
976
  "start": 300,
279
- "density": 0.0014707546102500305
977
+ "density": 0.015831134564643756
978
+ }
979
+ ],
980
+ "percentiles": {
981
+ "p75": 17
982
+ }
983
+ },
984
+ "interaction_to_next_paint": {
985
+ "histogram": [
986
+ {
987
+ "start": 0,
988
+ "end": 200,
989
+ "density": 0.6478405315614636
990
+ },
991
+ {
992
+ "start": 200,
993
+ "end": 500,
994
+ "density": 0.24584717607973486
995
+ },
996
+ {
997
+ "start": 500,
998
+ "density": 0.10631229235880371
280
999
  }
281
1000
  ],
282
1001
  "percentiles": {
283
- "p75": 19
1002
+ "p75": 272
284
1003
  }
285
1004
  },
286
1005
  "largest_contentful_paint": {
@@ -288,20 +1007,20 @@ curl -d origin='https://github.com' \
288
1007
  {
289
1008
  "start": 0,
290
1009
  "end": 2500,
291
- "density": 0.88479181369088589
1010
+ "density": 0.7900432900432863
292
1011
  },
293
1012
  {
294
1013
  "start": 2500,
295
1014
  "end": 4000,
296
- "density": 0.0809809456598438
1015
+ "density": 0.13528138528138467
297
1016
  },
298
1017
  {
299
1018
  "start": 4000,
300
- "density": 0.034227240649258875
1019
+ "density": 0.0746753246753239
301
1020
  }
302
1021
  ],
303
1022
  "percentiles": {
304
- "p75": 1775
1023
+ "p75": 2312
305
1024
  }
306
1025
  },
307
1026
  "cumulative_layout_shift": {
@@ -309,43 +1028,76 @@ curl -d origin='https://github.com' \
309
1028
  {
310
1029
  "start": "0.00",
311
1030
  "end": "0.10",
312
- "density": 0.869868589370856
1031
+ "density": 0.8527302813017104
313
1032
  },
314
1033
  {
315
1034
  "start": "0.10",
316
1035
  "end": "0.25",
317
- "density": 0.076636818234678356
1036
+ "density": 0.09817981246552682
318
1037
  },
319
1038
  {
320
1039
  "start": "0.25",
321
- "density": 0.053494592394464843
1040
+ "density": 0.04908990623276335
1041
+ }
1042
+ ],
1043
+ "percentiles": {
1044
+ "p75": "0.02"
1045
+ }
1046
+ },
1047
+ "experimental_time_to_first_byte": {
1048
+ "histogram": [
1049
+ {
1050
+ "start": 0,
1051
+ "end": 800,
1052
+ "density": 0.6018518518518505
1053
+ },
1054
+ {
1055
+ "start": 800,
1056
+ "end": 1800,
1057
+ "density": 0.3312757201646084
1058
+ },
1059
+ {
1060
+ "start": 1800,
1061
+ "density": 0.0668724279835391
322
1062
  }
323
1063
  ],
324
1064
  "percentiles": {
325
- "p75": "0.05"
1065
+ "p75": 1039
326
1066
  }
327
1067
  },
328
1068
  "first_contentful_paint": {
329
1069
  "histogram": [
330
1070
  {
331
1071
  "start": 0,
332
- "end": 1000,
333
- "density": 0.46447119924457247
1072
+ "end": 1800,
1073
+ "density": 0.7165570175438571
334
1074
  },
335
1075
  {
336
- "start": 1000,
1076
+ "start": 1800,
337
1077
  "end": 3000,
338
- "density": 0.48642587346553579
1078
+ "density": 0.1781798245614029
339
1079
  },
340
1080
  {
341
1081
  "start": 3000,
342
- "density": 0.049102927289896459
1082
+ "density": 0.10526315789473623
343
1083
  }
344
1084
  ],
345
1085
  "percentiles": {
346
- "p75": 1572
1086
+ "p75": 1934
347
1087
  }
348
1088
  }
1089
+ },
1090
+ "collectionPeriod": {
1091
+ "firstDate": {
1092
+ "year": 2023,
1093
+ "month": 9,
1094
+ "day": 15
1095
+ },
1096
+ "lastDate": {
1097
+ "year": 2023,
1098
+ "month": 10,
1099
+ "day": 12
1100
+ }
349
1101
  }
350
1102
  }
351
1103
  }