@samitouri / QOS-React-2 / commits / e5f6b91d29

Add Lane labels to scheduling profiler marks (#20808)

This commit changes scheduling profiler marks from a format like '--schedule-render-1' to '--schedule-render-1-Sync' (where 1 is the numeric value of the Sync lane). This will enable the profiler itself to show more meaningful labels for updates and render work. The commit also refactors and adds additional tests for the scheduling profiler package. It also updates the preprocessor to 'support' instant events. These are no-ops for us, but adding recognition of the event type will prevent profiles imported from e.g. Chrome Canary from throwing with an 'unrecognized event' error. (This will resolve issue #20767.)

Brian Vaughn committed Feb 23, 2021 at 11:31 UTC e5f6b91d294d0c1260ce5079ed0192b43ccd3e82
13 files changed +1055 -1817
packages/react-devtools-scheduling-profiler/src/EventTooltip.js
+6 -2
@@ -249,7 +249,7 @@ const TooltipReactMeasure = ({
249 return null;
250 }
251
252 - const {batchUID, duration, timestamp, lanes} = measure;
252 + const {batchUID, duration, timestamp, lanes, laneLabels} = measure;
253 const [startTime, stopTime] = getBatchRange(batchUID, data);
254
255 return (
@@ -265,7 +265,11 @@ const TooltipReactMeasure = ({
265 <div className={styles.DetailsGridLabel}>
266 Lane{lanes.length === 1 ? '' : 's'}:
267 </div>
268 - <div>{lanes.join(', ')}</div>
268 + <div>
269 + {laneLabels.length > 0
270 + ? `${laneLabels.join(', ')} (${lanes.join(', ')})`
271 + : lanes.join(', ')}
272 + </div>
273 </div>
274 </div>
275 );
packages/react-devtools-scheduling-profiler/src/constants.js
+2 -1
@@ -11,5 +11,6 @@ export {
11 COMFORTABLE_LINE_HEIGHT,
12 COMPACT_LINE_HEIGHT,
13 } from 'react-devtools-shared/src/constants.js';
14 +import {TotalLanes} from 'react-reconciler/src/ReactFiberLane.new';
15
15 -export const REACT_TOTAL_NUM_LANES = 31;
16 +export const REACT_TOTAL_NUM_LANES = TotalLanes;
packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/__snapshots__/preprocessData-test.js.snap deleted
-1380
@@ -1,1380 +0,0 @@
1 -// Jest Snapshot v1, https://goo.gl/fbAQLP
2 -
3 -exports[`preprocessData should process complete set of events (page load sample data) 1`] = `
4 -Object {
5 - "duration": 2586.895,
6 - "events": Array [
7 - Object {
8 - "componentStack": "",
9 - "lanes": Array [
10 - 9,
11 - ],
12 - "timestamp": 278.073,
13 - "type": "schedule-render",
14 - },
15 - Object {
16 - "componentName": "ResourceButton",
17 - "componentStack": "
18 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
19 - at Suspense
20 - at div
21 - at div
22 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
23 - at App",
24 - "id": "0",
25 - "timestamp": 658.345,
26 - "type": "suspense-suspend",
27 - },
28 - Object {
29 - "componentName": "ResourceButton",
30 - "componentStack": "
31 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
32 - at Suspense
33 - at div
34 - at div
35 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
36 - at App",
37 - "id": "1",
38 - "timestamp": 660.739,
39 - "type": "suspense-suspend",
40 - },
41 - Object {
42 - "componentName": "ResourceButton",
43 - "componentStack": "
44 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
45 - at Suspense
46 - at div
47 - at div
48 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
49 - at App",
50 - "id": "2",
51 - "timestamp": 662.554,
52 - "type": "suspense-suspend",
53 - },
54 - Object {
55 - "componentName": "ResourceButton",
56 - "componentStack": "
57 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
58 - at Suspense
59 - at div
60 - at div
61 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
62 - at App",
63 - "id": "3",
64 - "timestamp": 663.455,
65 - "type": "suspense-suspend",
66 - },
67 - Object {
68 - "componentName": "ResourceButton",
69 - "componentStack": "
70 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
71 - at Suspense
72 - at div
73 - at div
74 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
75 - at App",
76 - "id": "4",
77 - "timestamp": 664.202,
78 - "type": "suspense-suspend",
79 - },
80 - Object {
81 - "componentName": "ResourceButton",
82 - "componentStack": "
83 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
84 - at Suspense
85 - at div
86 - at div
87 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
88 - at App",
89 - "id": "0",
90 - "timestamp": 666.68,
91 - "type": "suspense-suspend",
92 - },
93 - Object {
94 - "componentName": "ResourceButton",
95 - "componentStack": "
96 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
97 - at Suspense
98 - at div
99 - at div
100 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
101 - at App",
102 - "id": "1",
103 - "timestamp": 667.201,
104 - "type": "suspense-suspend",
105 - },
106 - Object {
107 - "componentName": "ResourceButton",
108 - "componentStack": "
109 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
110 - at Suspense
111 - at div
112 - at div
113 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
114 - at App",
115 - "id": "2",
116 - "timestamp": 667.74,
117 - "type": "suspense-suspend",
118 - },
119 - Object {
120 - "componentName": "ResourceButton",
121 - "componentStack": "
122 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
123 - at Suspense
124 - at div
125 - at div
126 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
127 - at App",
128 - "id": "3",
129 - "timestamp": 668.282,
130 - "type": "suspense-suspend",
131 - },
132 - Object {
133 - "componentName": "ResourceButton",
134 - "componentStack": "
135 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
136 - at Suspense
137 - at div
138 - at div
139 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
140 - at App",
141 - "id": "4",
142 - "timestamp": 668.848,
143 - "type": "suspense-suspend",
144 - },
145 - Object {
146 - "componentName": "ResourceButton",
147 - "componentStack": "
148 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
149 - at Suspense
150 - at SuspenseList
151 - at div
152 - at div
153 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
154 - at App",
155 - "id": "0",
156 - "timestamp": 671.335,
157 - "type": "suspense-suspend",
158 - },
159 - Object {
160 - "componentName": "ForceUpdateDemo_ForceUpdateDemo",
161 - "componentStack": "
162 - at ForceUpdateDemo_ForceUpdateDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:18:98)
163 - at App",
164 - "isCascading": true,
165 - "lanes": Array [
166 - 0,
167 - ],
168 - "timestamp": 679.438,
169 - "type": "schedule-state-update",
170 - },
171 - Object {
172 - "componentName": "ResourceButton",
173 - "componentStack": "
174 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
175 - at Suspense
176 - at div
177 - at div
178 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
179 - at App",
180 - "id": "1",
181 - "timestamp": 1794.922,
182 - "type": "suspense-resolved",
183 - },
184 - Object {
185 - "componentName": "ResourceButton",
186 - "componentStack": "
187 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
188 - at Suspense
189 - at div
190 - at div
191 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
192 - at App",
193 - "id": "1",
194 - "timestamp": 1795.374,
195 - "type": "suspense-resolved",
196 - },
197 - Object {
198 - "componentName": "ResourceButton",
199 - "componentStack": "
200 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
201 - at Suspense
202 - at div
203 - at div
204 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
205 - at App",
206 - "id": "0",
207 - "timestamp": 1797.166,
208 - "type": "suspense-suspend",
209 - },
210 - Object {
211 - "componentName": "ResourceButton",
212 - "componentStack": "
213 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
214 - at Suspense
215 - at div
216 - at div
217 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
218 - at App",
219 - "id": "2",
220 - "timestamp": 1797.811,
221 - "type": "suspense-suspend",
222 - },
223 - Object {
224 - "componentName": "ResourceButton",
225 - "componentStack": "
226 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
227 - at Suspense
228 - at div
229 - at div
230 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
231 - at App",
232 - "id": "3",
233 - "timestamp": 1798.163,
234 - "type": "suspense-suspend",
235 - },
236 - Object {
237 - "componentName": "ResourceButton",
238 - "componentStack": "
239 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
240 - at Suspense
241 - at div
242 - at div
243 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
244 - at App",
245 - "id": "4",
246 - "timestamp": 1798.505,
247 - "type": "suspense-suspend",
248 - },
249 - Object {
250 - "componentName": "ResourceButton",
251 - "componentStack": "
252 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
253 - at Suspense
254 - at div
255 - at div
256 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
257 - at App",
258 - "id": "2",
259 - "timestamp": 1866.249,
260 - "type": "suspense-resolved",
261 - },
262 - Object {
263 - "componentName": "ResourceButton",
264 - "componentStack": "
265 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
266 - at Suspense
267 - at div
268 - at div
269 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
270 - at App",
271 - "id": "2",
272 - "timestamp": 1866.542,
273 - "type": "suspense-resolved",
274 - },
275 - Object {
276 - "componentName": "ResourceButton",
277 - "componentStack": "
278 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
279 - at Suspense
280 - at div
281 - at div
282 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
283 - at App",
284 - "id": "2",
285 - "timestamp": 1866.858,
286 - "type": "suspense-resolved",
287 - },
288 - Object {
289 - "componentName": "ResourceButton",
290 - "componentStack": "
291 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
292 - at Suspense
293 - at div
294 - at div
295 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
296 - at App",
297 - "id": "0",
298 - "timestamp": 1867.816,
299 - "type": "suspense-suspend",
300 - },
301 - Object {
302 - "componentName": "ResourceButton",
303 - "componentStack": "
304 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
305 - at Suspense
306 - at div
307 - at div
308 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
309 - at App",
310 - "id": "3",
311 - "timestamp": 1868.638,
312 - "type": "suspense-suspend",
313 - },
314 - Object {
315 - "componentName": "ResourceButton",
316 - "componentStack": "
317 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
318 - at Suspense
319 - at div
320 - at div
321 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
322 - at App",
323 - "id": "4",
324 - "timestamp": 1868.966,
325 - "type": "suspense-suspend",
326 - },
327 - Object {
328 - "componentName": "ResourceButton",
329 - "componentStack": "
330 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
331 - at Suspense
332 - at div
333 - at div
334 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
335 - at App",
336 - "id": "3",
337 - "timestamp": 1980.273,
338 - "type": "suspense-resolved",
339 - },
340 - Object {
341 - "componentName": "ResourceButton",
342 - "componentStack": "
343 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
344 - at Suspense
345 - at div
346 - at div
347 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
348 - at App",
349 - "id": "3",
350 - "timestamp": 1980.522,
351 - "type": "suspense-resolved",
352 - },
353 - Object {
354 - "componentName": "ResourceButton",
355 - "componentStack": "
356 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
357 - at Suspense
358 - at div
359 - at div
360 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
361 - at App",
362 - "id": "3",
363 - "timestamp": 1980.946,
364 - "type": "suspense-resolved",
365 - },
366 - Object {
367 - "componentName": "ResourceButton",
368 - "componentStack": "
369 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
370 - at Suspense
371 - at div
372 - at div
373 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
374 - at App",
375 - "id": "3",
376 - "timestamp": 1981.164,
377 - "type": "suspense-resolved",
378 - },
379 - Object {
380 - "componentName": "ResourceButton",
381 - "componentStack": "
382 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
383 - at Suspense
384 - at div
385 - at div
386 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
387 - at App",
388 - "id": "0",
389 - "timestamp": 1982.079,
390 - "type": "suspense-suspend",
391 - },
392 - Object {
393 - "componentName": "ResourceButton",
394 - "componentStack": "
395 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
396 - at Suspense
397 - at div
398 - at div
399 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
400 - at App",
401 - "id": "4",
402 - "timestamp": 1983.17,
403 - "type": "suspense-suspend",
404 - },
405 - Object {
406 - "componentName": "ResourceButton",
407 - "componentStack": "
408 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
409 - at Suspense
410 - at div
411 - at div
412 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
413 - at App",
414 - "id": "4",
415 - "timestamp": 2379.587,
416 - "type": "suspense-resolved",
417 - },
418 - Object {
419 - "componentName": "ResourceButton",
420 - "componentStack": "
421 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
422 - at Suspense
423 - at div
424 - at div
425 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
426 - at App",
427 - "id": "4",
428 - "timestamp": 2379.895,
429 - "type": "suspense-resolved",
430 - },
431 - Object {
432 - "componentName": "ResourceButton",
433 - "componentStack": "
434 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
435 - at Suspense
436 - at div
437 - at div
438 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
439 - at App",
440 - "id": "4",
441 - "timestamp": 2380.242,
442 - "type": "suspense-resolved",
443 - },
444 - Object {
445 - "componentName": "ResourceButton",
446 - "componentStack": "
447 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
448 - at Suspense
449 - at div
450 - at div
451 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
452 - at App",
453 - "id": "4",
454 - "timestamp": 2380.487,
455 - "type": "suspense-resolved",
456 - },
457 - Object {
458 - "componentName": "ResourceButton",
459 - "componentStack": "
460 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
461 - at Suspense
462 - at div
463 - at div
464 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
465 - at App",
466 - "id": "4",
467 - "timestamp": 2380.735,
468 - "type": "suspense-resolved",
469 - },
470 - Object {
471 - "componentName": "ResourceButton",
472 - "componentStack": "
473 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
474 - at Suspense
475 - at div
476 - at div
477 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
478 - at App",
479 - "id": "0",
480 - "timestamp": 2381.772,
481 - "type": "suspense-suspend",
482 - },
483 - Object {
484 - "componentName": "ResourceButton",
485 - "componentStack": "
486 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
487 - at Suspense
488 - at div
489 - at div
490 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
491 - at App",
492 - "id": "0",
493 - "timestamp": 2579.186,
494 - "type": "suspense-resolved",
495 - },
496 - Object {
497 - "componentName": "ResourceButton",
498 - "componentStack": "
499 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
500 - at Suspense
501 - at div
502 - at div
503 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
504 - at App",
505 - "id": "0",
506 - "timestamp": 2579.487,
507 - "type": "suspense-resolved",
508 - },
509 - Object {
510 - "componentName": "ResourceButton",
511 - "componentStack": "
512 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
513 - at Suspense
514 - at SuspenseList
515 - at div
516 - at div
517 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
518 - at App",
519 - "id": "0",
520 - "timestamp": 2579.735,
521 - "type": "suspense-resolved",
522 - },
523 - Object {
524 - "componentName": "ResourceButton",
525 - "componentStack": "
526 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
527 - at Suspense
528 - at div
529 - at div
530 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
531 - at App",
532 - "id": "0",
533 - "timestamp": 2580.042,
534 - "type": "suspense-resolved",
535 - },
536 - Object {
537 - "componentName": "ResourceButton",
538 - "componentStack": "
539 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
540 - at Suspense
541 - at div
542 - at div
543 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
544 - at App",
545 - "id": "0",
546 - "timestamp": 2580.29,
547 - "type": "suspense-resolved",
548 - },
549 - Object {
550 - "componentName": "ResourceButton",
551 - "componentStack": "
552 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
553 - at Suspense
554 - at div
555 - at div
556 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
557 - at App",
558 - "id": "0",
559 - "timestamp": 2580.546,
560 - "type": "suspense-resolved",
561 - },
562 - Object {
563 - "componentName": "ResourceButton",
564 - "componentStack": "
565 - at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)
566 - at Suspense
567 - at div
568 - at div
569 - at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)
570 - at App",
571 - "id": "0",
572 - "timestamp": 2580.8,
573 - "type": "suspense-resolved",
574 - },
575 - ],
576 - "flamechart": Array [],
577 - "measures": Array [
578 - Object {
579 - "batchUID": 0,
580 - "depth": 0,
581 - "duration": 402.58299999999997,
582 - "lanes": Array [
583 - 9,
584 - ],
585 - "timestamp": 285.293,
586 - "type": "render-idle",
587 - },
588 - Object {
589 - "batchUID": 0,
590 - "depth": 0,
591 - "duration": 5.235000000000014,
592 - "lanes": Array [
593 - 9,
594 - ],
595 - "timestamp": 285.293,
596 - "type": "render",
597 - },
598 - Object {
599 - "batchUID": 0,
600 - "depth": 0,
601 - "duration": 8.16799999999995,
602 - "lanes": Array [
603 - 9,
604 - ],
605 - "timestamp": 297.708,
606 - "type": "render",
607 - },
608 - Object {
609 - "batchUID": 0,
610 - "depth": 0,
611 - "duration": 4.989000000000033,
612 - "lanes": Array [
613 - 9,
614 - ],
615 - "timestamp": 310.457,
616 - "type": "render",
617 - },
618 - Object {
619 - "batchUID": 0,
620 - "depth": 0,
621 - "duration": 6.470000000000027,
622 - "lanes": Array [
623 - 9,
624 - ],
625 - "timestamp": 357.767,
626 - "type": "render",
627 - },
628 - Object {
629 - "batchUID": 0,
630 - "depth": 0,
631 - "duration": 6.633000000000038,
632 - "lanes": Array [
633 - 9,
634 - ],
635 - "timestamp": 371.486,
636 - "type": "render",
637 - },
638 - Object {
639 - "batchUID": 0,
640 - "depth": 0,
641 - "duration": 9.889999999999986,
642 - "lanes": Array [
643 - 9,
644 - ],
645 - "timestamp": 385.05,
646 - "type": "render",
647 - },
648 - Object {
649 - "batchUID": 0,
650 - "depth": 0,
651 - "duration": 7.8589999999999804,
652 - "lanes": Array [
653 - 9,
654 - ],
655 - "timestamp": 398.06,
656 - "type": "render",
657 - },
658 - Object {
659 - "batchUID": 0,
660 - "depth": 0,
661 - "duration": 7.261000000000024,
662 - "lanes": Array [
663 - 9,
664 - ],
665 - "timestamp": 406.666,
666 - "type": "render",
667 - },
668 - Object {
669 - "batchUID": 0,
670 - "depth": 0,
671 - "duration": 7.700999999999965,
672 - "lanes": Array [
673 - 9,
674 - ],
675 - "timestamp": 414.218,
676 - "type": "render",
677 - },
678 - Object {
679 - "batchUID": 0,
680 - "depth": 0,
681 - "duration": 7.793000000000006,
682 - "lanes": Array [
683 - 9,
684 - ],
685 - "timestamp": 422.141,
686 - "type": "render",
687 - },
688 - Object {
689 - "batchUID": 0,
690 - "depth": 0,
691 - "duration": 7.706999999999994,
692 - "lanes": Array [
693 - 9,
694 - ],
695 - "timestamp": 430.185,
696 - "type": "render",
697 - },
698 - Object {
699 - "batchUID": 0,
700 - "depth": 0,
701 - "duration": 7.406999999999982,
702 - "lanes": Array [
703 - 9,
704 - ],
705 - "timestamp": 439.552,
706 - "type": "render",
707 - },
708 - Object {
709 - "batchUID": 0,
710 - "depth": 0,
711 - "duration": 7.649000000000001,
712 - "lanes": Array [
713 - 9,
714 - ],
715 - "timestamp": 447.294,
716 - "type": "render",
717 - },
718 - Object {
719 - "batchUID": 0,
720 - "depth": 0,
721 - "duration": 7.736000000000047,
722 - "lanes": Array [
723 - 9,
724 - ],
725 - "timestamp": 455.215,
726 - "type": "render",
727 - },
728 - Object {
729 - "batchUID": 0,
730 - "depth": 0,
731 - "duration": 7.6959999999999695,
732 - "lanes": Array [
733 - 9,
734 - ],
735 - "timestamp": 463.259,
736 - "type": "render",
737 - },
738 - Object {
739 - "batchUID": 0,
740 - "depth": 0,
741 - "duration": 7.700999999999965,
742 - "lanes": Array [
743 - 9,
744 - ],
745 - "timestamp": 471.247,
746 - "type": "render",
747 - },
748 - Object {
749 - "batchUID": 0,
750 - "depth": 0,
751 - "duration": 7.55499999999995,
752 - "lanes": Array [
753 - 9,
754 - ],
755 - "timestamp": 479.362,
756 - "type": "render",
757 - },
758 - Object {
759 - "batchUID": 0,
760 - "depth": 0,
761 - "duration": 7.7900000000000205,
762 - "lanes": Array [
763 - 9,
764 - ],
765 - "timestamp": 487.195,
766 - "type": "render",
767 - },
768 - Object {
769 - "batchUID": 0,
770 - "depth": 0,
771 - "duration": 7.617000000000019,
772 - "lanes": Array [
773 - 9,
774 - ],
775 - "timestamp": 495.354,
776 - "type": "render",
777 - },
778 - Object {
779 - "batchUID": 0,
780 - "depth": 0,
781 - "duration": 7.241999999999962,
782 - "lanes": Array [
783 - 9,
784 - ],
785 - "timestamp": 503.706,
786 - "type": "render",
787 - },
788 - Object {
789 - "batchUID": 0,
790 - "depth": 0,
791 - "duration": 7.81899999999996,
792 - "lanes": Array [
793 - 9,
794 - ],
795 - "timestamp": 513.106,
796 - "type": "render",
797 - },
798 - Object {
799 - "batchUID": 0,
800 - "depth": 0,
801 - "duration": 9.269999999999982,
802 - "lanes": Array [
803 - 9,
804 - ],
805 - "timestamp": 521.667,
806 - "type": "render",
807 - },
808 - Object {
809 - "batchUID": 0,
810 - "depth": 0,
811 - "duration": 7.758000000000038,
812 - "lanes": Array [
813 - 9,
814 - ],
815 - "timestamp": 531.185,
816 - "type": "render",
817 - },
818 - Object {
819 - "batchUID": 0,
820 - "depth": 0,
821 - "duration": 7.735000000000014,
822 - "lanes": Array [
823 - 9,
824 - ],
825 - "timestamp": 539.213,
826 - "type": "render",
827 - },
828 - Object {
829 - "batchUID": 0,
830 - "depth": 0,
831 - "duration": 7.730000000000018,
832 - "lanes": Array [
833 - 9,
834 - ],
835 - "timestamp": 547.223,
836 - "type": "render",
837 - },
838 - Object {
839 - "batchUID": 0,
840 - "depth": 0,
841 - "duration": 7.697000000000003,
842 - "lanes": Array [
843 - 9,
844 - ],
845 - "timestamp": 555.234,
846 - "type": "render",
847 - },
848 - Object {
849 - "batchUID": 0,
850 - "depth": 0,
851 - "duration": 7.715000000000032,
852 - "lanes": Array [
853 - 9,
854 - ],
855 - "timestamp": 563.232,
856 - "type": "render",
857 - },
858 - Object {
859 - "batchUID": 0,
860 - "depth": 0,
861 - "duration": 7.760999999999967,
862 - "lanes": Array [
863 - 9,
864 - ],
865 - "timestamp": 571.212,
866 - "type": "render",
867 - },
868 - Object {
869 - "batchUID": 0,
870 - "depth": 0,
871 - "duration": 7.618000000000052,
872 - "lanes": Array [
873 - 9,
874 - ],
875 - "timestamp": 579.324,
876 - "type": "render",
877 - },
878 - Object {
879 - "batchUID": 0,
880 - "depth": 0,
881 - "duration": 7.737999999999943,
882 - "lanes": Array [
883 - 9,
884 - ],
885 - "timestamp": 587.201,
886 - "type": "render",
887 - },
888 - Object {
889 - "batchUID": 0,
890 - "depth": 0,
891 - "duration": 7.739000000000033,
892 - "lanes": Array [
893 - 9,
894 - ],
895 - "timestamp": 595.209,
896 - "type": "render",
897 - },
898 - Object {
899 - "batchUID": 0,
900 - "depth": 0,
901 - "duration": 7.732000000000085,
902 - "lanes": Array [
903 - 9,
904 - ],
905 - "timestamp": 603.194,
906 - "type": "render",
907 - },
908 - Object {
909 - "batchUID": 0,
910 - "depth": 0,
911 - "duration": 7.712999999999965,
912 - "lanes": Array [
913 - 9,
914 - ],
915 - "timestamp": 611.212,
916 - "type": "render",
917 - },
918 - Object {
919 - "batchUID": 0,
920 - "depth": 0,
921 - "duration": 7.3700000000000045,
922 - "lanes": Array [
923 - 9,
924 - ],
925 - "timestamp": 619.574,
926 - "type": "render",
927 - },
928 - Object {
929 - "batchUID": 0,
930 - "depth": 0,
931 - "duration": 7.73599999999999,
932 - "lanes": Array [
933 - 9,
934 - ],
935 - "timestamp": 627.188,
936 - "type": "render",
937 - },
938 - Object {
939 - "batchUID": 0,
940 - "depth": 0,
941 - "duration": 7.729000000000042,
942 - "lanes": Array [
943 - 9,
944 - ],
945 - "timestamp": 635.193,
946 - "type": "render",
947 - },
948 - Object {
949 - "batchUID": 0,
950 - "depth": 0,
951 - "duration": 7.908999999999992,
952 - "lanes": Array [
953 - 9,
954 - ],
955 - "timestamp": 643.206,
956 - "type": "render",
957 - },
958 - Object {
959 - "batchUID": 0,
960 - "depth": 0,
961 - "duration": 7.6159999999999854,
962 - "lanes": Array [
963 - 9,
964 - ],
965 - "timestamp": 651.339,
966 - "type": "render",
967 - },
968 - Object {
969 - "batchUID": 0,
970 - "depth": 0,
971 - "duration": 5.334999999999923,
972 - "lanes": Array [
973 - 9,
974 - ],
975 - "timestamp": 659.445,
976 - "type": "render",
977 - },
978 - Object {
979 - "batchUID": 0,
980 - "depth": 0,
981 - "duration": 5.5890000000000555,
982 - "lanes": Array [
983 - 9,
984 - ],
985 - "timestamp": 664.952,
986 - "type": "render",
987 - },
988 - Object {
989 - "batchUID": 0,
990 - "depth": 0,
991 - "duration": 1.58400000000006,
992 - "lanes": Array [
993 - 9,
994 - ],
995 - "timestamp": 670.784,
996 - "type": "render",
997 - },
998 - Object {
999 - "batchUID": 0,
1000 - "depth": 0,
1001 - "duration": 14.552000000000021,
1002 - "lanes": Array [
1003 - 9,
1004 - ],
1005 - "timestamp": 673.324,
1006 - "type": "commit",
1007 - },
1008 - Object {
1009 - "batchUID": 0,
1010 - "depth": 1,
1011 - "duration": 2.6889999999999645,
1012 - "lanes": Array [
1013 - 9,
1014 - ],
1015 - "timestamp": 677.236,
1016 - "type": "layout-effects",
1017 - },
1018 - Object {
1019 - "batchUID": 1,
1020 - "depth": 1,
1021 - "duration": 3.5559999999999263,
1022 - "lanes": Array [
1023 - 0,
1024 - ],
1025 - "timestamp": 684.104,
1026 - "type": "render-idle",
1027 - },
1028 - Object {
1029 - "batchUID": 1,
1030 - "depth": 1,
1031 - "duration": 2.2169999999999845,
1032 - "lanes": Array [
1033 - 0,
1034 - ],
1035 - "timestamp": 684.104,
1036 - "type": "render",
1037 - },
1038 - Object {
1039 - "batchUID": 1,
1040 - "depth": 1,
1041 - "duration": 1.3120000000000118,
1042 - "lanes": Array [
1043 - 0,
1044 - ],
1045 - "timestamp": 686.348,
1046 - "type": "commit",
1047 - },
1048 - Object {
1049 - "batchUID": 1,
1050 - "depth": 2,
1051 - "duration": 0.020999999999958163,
1052 - "lanes": Array [
1053 - 0,
1054 - ],
1055 - "timestamp": 687.267,
1056 - "type": "layout-effects",
1057 - },
1058 - Object {
1059 - "batchUID": 2,
1060 - "depth": 0,
1061 - "duration": 6.119000000000142,
1062 - "lanes": Array [
1063 - 10,
1064 - ],
1065 - "timestamp": 1796.042,
1066 - "type": "render-idle",
1067 - },
1068 - Object {
1069 - "batchUID": 2,
1070 - "depth": 0,
1071 - "duration": 3.4329999999999927,
1072 - "lanes": Array [
1073 - 10,
1074 - ],
1075 - "timestamp": 1796.042,
1076 - "type": "render",
1077 - },
1078 - Object {
1079 - "batchUID": 2,
1080 - "depth": 0,
1081 - "duration": 2.589000000000169,
1082 - "lanes": Array [
1083 - 10,
1084 - ],
1085 - "timestamp": 1799.572,
1086 - "type": "commit",
1087 - },
1088 - Object {
1089 - "batchUID": 2,
1090 - "depth": 1,
1091 - "duration": 0.020999999999958163,
1092 - "lanes": Array [
1093 - 10,
1094 - ],
1095 - "timestamp": 1801.605,
1096 - "type": "layout-effects",
1097 - },
1098 - Object {
1099 - "batchUID": 3,
1100 - "depth": 0,
1101 - "duration": 4.116999999999962,
1102 - "lanes": Array [
1103 - 11,
1104 - ],
1105 - "timestamp": 1866.998,
1106 - "type": "render-idle",
1107 - },
1108 - Object {
1109 - "batchUID": 3,
1110 - "depth": 0,
1111 - "duration": 2.6679999999998927,
1112 - "lanes": Array [
1113 - 11,
1114 - ],
1115 - "timestamp": 1866.998,
1116 - "type": "render",
1117 - },
1118 - Object {
1119 - "batchUID": 3,
1120 - "depth": 0,
1121 - "duration": 1.4200000000000728,
1122 - "lanes": Array [
1123 - 11,
1124 - ],
1125 - "timestamp": 1869.695,
1126 - "type": "commit",
1127 - },
1128 - Object {
1129 - "batchUID": 3,
1130 - "depth": 1,
1131 - "duration": 0.020000000000209184,
1132 - "lanes": Array [
1133 - 11,
1134 - ],
1135 - "timestamp": 1870.764,
1136 - "type": "layout-effects",
1137 - },
1138 - Object {
1139 - "batchUID": 4,
1140 - "depth": 0,
1141 - "duration": 3.7679999999998017,
1142 - "lanes": Array [
1143 - 12,
1144 - ],
1145 - "timestamp": 1981.361,
1146 - "type": "render-idle",
1147 - },
1148 - Object {
1149 - "batchUID": 4,
1150 - "depth": 0,
1151 - "duration": 2.438999999999851,
1152 - "lanes": Array [
1153 - 12,
1154 - ],
1155 - "timestamp": 1981.361,
1156 - "type": "render",
1157 - },
1158 - Object {
1159 - "batchUID": 4,
1160 - "depth": 0,
1161 - "duration": 1.2579999999998108,
1162 - "lanes": Array [
1163 - 12,
1164 - ],
1165 - "timestamp": 1983.871,
1166 - "type": "commit",
1167 - },
1168 - Object {
1169 - "batchUID": 4,
1170 - "depth": 1,
1171 - "duration": 0.027000000000043656,
1172 - "lanes": Array [
1173 - 12,
1174 - ],
1175 - "timestamp": 1984.931,
1176 - "type": "layout-effects",
1177 - },
1178 - Object {
1179 - "batchUID": 5,
1180 - "depth": 0,
1181 - "duration": 3.8899999999998727,
1182 - "lanes": Array [
1183 - 13,
1184 - ],
1185 - "timestamp": 2380.969,
1186 - "type": "render-idle",
1187 - },
1188 - Object {
1189 - "batchUID": 5,
1190 - "depth": 0,
1191 - "duration": 2.3099999999999454,
1192 - "lanes": Array [
1193 - 13,
1194 - ],
1195 - "timestamp": 2380.969,
1196 - "type": "render",
1197 - },
1198 - Object {
1199 - "batchUID": 5,
1200 - "depth": 0,
1201 - "duration": 1.5209999999997308,
1202 - "lanes": Array [
1203 - 13,
1204 - ],
1205 - "timestamp": 2383.338,
1206 - "type": "commit",
1207 - },
1208 - Object {
1209 - "batchUID": 5,
1210 - "depth": 1,
1211 - "duration": 0.01999999999998181,
1212 - "lanes": Array [
1213 - 13,
1214 - ],
1215 - "timestamp": 2384.535,
1216 - "type": "layout-effects",
1217 - },
1218 - Object {
1219 - "batchUID": 6,
1220 - "depth": 0,
1221 - "duration": 5.942999999999756,
1222 - "lanes": Array [
1223 - 14,
1224 - ],
1225 - "timestamp": 2580.952,
1226 - "type": "render-idle",
1227 - },
1228 - Object {
1229 - "batchUID": 6,
1230 - "depth": 0,
1231 - "duration": 3.424999999999727,
1232 - "lanes": Array [
1233 - 14,
1234 - ],
1235 - "timestamp": 2580.952,
1236 - "type": "render",
1237 - },
1238 - Object {
1239 - "batchUID": 6,
1240 - "depth": 0,
1241 - "duration": 2.4470000000001164,
1242 - "lanes": Array [
1243 - 14,
1244 - ],
1245 - "timestamp": 2584.448,
1246 - "type": "commit",
1247 - },
1248 - Object {
1249 - "batchUID": 6,
1250 - "depth": 1,
1251 - "duration": 0.027000000000043656,
1252 - "lanes": Array [
1253 - 14,
1254 - ],
1255 - "timestamp": 2586.122,
1256 - "type": "layout-effects",
1257 - },
1258 - ],
1259 - "otherUserTimingMarks": Array [
1260 - Object {
1261 - "name": "navigationStart",
1262 - "timestamp": -29.357,
1263 - },
1264 - Object {
1265 - "name": "fetchStart",
1266 - "timestamp": -26.92,
1267 - },
1268 - Object {
1269 - "name": "requestStart",
1270 - "timestamp": -21.171,
1271 - },
1272 - Object {
1273 - "name": "responseEnd",
1274 - "timestamp": -15.655,
1275 - },
1276 - Object {
1277 - "name": "unloadEventStart",
1278 - "timestamp": -0.74,
1279 - },
1280 - Object {
1281 - "name": "unloadEventEnd",
1282 - "timestamp": 39.608,
1283 - },
1284 - Object {
1285 - "name": "requestStart",
1286 - "timestamp": 107.649,
1287 - },
1288 - Object {
1289 - "name": "requestStart",
1290 - "timestamp": 108.385,
1291 - },
1292 - Object {
1293 - "name": "loadEventStart",
1294 - "timestamp": 307.056,
1295 - },
1296 - Object {
1297 - "name": "loadEventEnd",
1298 - "timestamp": 308.242,
1299 - },
1300 - Object {
1301 - "name": "requestStart",
1302 - "timestamp": 341.329,
1303 - },
1304 - Object {
1305 - "name": "requestStart",
1306 - "timestamp": 344.02,
1307 - },
1308 - Object {
1309 - "name": "requestStart",
1310 - "timestamp": 387.585,
1311 - },
1312 - ],
1313 - "startTime": 8993778496,
1314 -}
1315 -`;
1316 -
1317 -exports[`preprocessData should process forced update event 1`] = `
1318 -Object {
1319 - "duration": 67.461,
1320 - "events": Array [
1321 - Object {
1322 - "componentName": "ForceUpdateDemo_ForceUpdateDemo",
1323 - "componentStack": "
1324 - at ForceUpdateDemo_ForceUpdateDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:18:98)
1325 - at App",
1326 - "isCascading": false,
1327 - "lanes": Array [
1328 - 4,
1329 - ],
1330 - "timestamp": 63.355,
1331 - "type": "schedule-force-update",
1332 - },
1333 - ],
1334 - "flamechart": Array [],
1335 - "measures": Array [
1336 - Object {
1337 - "batchUID": 0,
1338 - "depth": 0,
1339 - "duration": 2.1910000000000025,
1340 - "lanes": Array [
1341 - 4,
1342 - ],
1343 - "timestamp": 65.27,
1344 - "type": "render-idle",
1345 - },
1346 - Object {
1347 - "batchUID": 0,
1348 - "depth": 0,
1349 - "duration": 0.9770000000000039,
1350 - "lanes": Array [
1351 - 4,
1352 - ],
1353 - "timestamp": 65.27,
1354 - "type": "render",
1355 - },
1356 - Object {
1357 - "batchUID": 0,
1358 - "depth": 0,
1359 - "duration": 1.1670000000000016,
1360 - "lanes": Array [
1361 - 4,
1362 - ],
1363 - "timestamp": 66.294,
1364 - "type": "commit",
1365 - },
1366 - Object {
1367 - "batchUID": 0,
1368 - "depth": 1,
1369 - "duration": 0.018000000000000682,
1370 - "lanes": Array [
1371 - 4,
1372 - ],
1373 - "timestamp": 67.325,
1374 - "type": "layout-effects",
1375 - },
1376 - ],
1377 - "otherUserTimingMarks": Array [],
1378 - "startTime": 40806924876,
1379 -}
1380 -`;
packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js new
+602
@@ -0,0 +1,602 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + */
7 +
8 +'use strict';
9 +
10 +import preprocessData, {
11 + getLanesFromTransportDecimalBitmask,
12 +} from '../preprocessData';
13 +import {REACT_TOTAL_NUM_LANES} from '../../constants';
14 +
15 +describe(getLanesFromTransportDecimalBitmask, () => {
16 + it('should return array of lane numbers from bitmask string', () => {
17 + expect(getLanesFromTransportDecimalBitmask('1')).toEqual([0]);
18 + expect(getLanesFromTransportDecimalBitmask('512')).toEqual([9]);
19 + expect(getLanesFromTransportDecimalBitmask('3')).toEqual([0, 1]);
20 + expect(getLanesFromTransportDecimalBitmask('1234')).toEqual([
21 + 1,
22 + 4,
23 + 6,
24 + 7,
25 + 10,
26 + ]); // 2 + 16 + 64 + 128 + 1024
27 + expect(
28 + getLanesFromTransportDecimalBitmask('1073741824'), // 0b1000000000000000000000000000000
29 + ).toEqual([30]);
30 + expect(
31 + getLanesFromTransportDecimalBitmask('2147483647'), // 0b1111111111111111111111111111111
32 + ).toEqual(Array.from(Array(31).keys()));
33 + });
34 +
35 + it('should return empty array if laneBitmaskString is not a bitmask', () => {
36 + expect(getLanesFromTransportDecimalBitmask('')).toEqual([]);
37 + expect(getLanesFromTransportDecimalBitmask('hello')).toEqual([]);
38 + expect(getLanesFromTransportDecimalBitmask('-1')).toEqual([]);
39 + expect(getLanesFromTransportDecimalBitmask('-0')).toEqual([]);
40 + });
41 +
42 + it('should ignore lanes outside REACT_TOTAL_NUM_LANES', () => {
43 + // Sanity check; this test may need to be updated when the no. of fiber
44 + // lanes are changed.
45 + expect(REACT_TOTAL_NUM_LANES).toBe(31);
46 +
47 + expect(
48 + getLanesFromTransportDecimalBitmask(
49 + '4294967297', // 2^32 + 1
50 + ),
51 + ).toEqual([0]);
52 + });
53 +});
54 +
55 +describe(preprocessData, () => {
56 + let React;
57 + let ReactDOM;
58 +
59 + let act;
60 + let clearedMarks;
61 + let featureDetectionMarkName = null;
62 + let marks;
63 +
64 + function polyfillJSDomUserTiming() {
65 + featureDetectionMarkName = null;
66 +
67 + clearedMarks = [];
68 + marks = [];
69 +
70 + // This is not a true polyfill, but it gives us enough to capture marks.
71 + // Reference: https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API
72 +
73 + // JSDom already implements global.performance and it can't be overridden.
74 + // However it only supports now() and timeOrigin() so we need to "upgrade it" in place.
75 +
76 + if (!global.performance) {
77 + global.performance = {};
78 + }
79 +
80 + global.performance.clearMarks = function clearMarks(markName) {
81 + clearedMarks.push(markName);
82 + marks = marks.filter(mark => mark !== markName);
83 + };
84 +
85 + global.performance.mark = function mark(markName, markOptions) {
86 + if (featureDetectionMarkName === null) {
87 + featureDetectionMarkName = markName;
88 + }
89 + marks.push(markName);
90 + if (markOptions != null) {
91 + // This is triggers the feature detection.
92 + markOptions.startTime++;
93 + }
94 + };
95 + }
96 +
97 + // These should be dynamic to mimic a real profile,
98 + // but reprooducible between test runs.
99 + let pid = 0;
100 + let tid = 0;
101 + let startTime = 0;
102 +
103 + function createUserTimingEntry(data) {
104 + return {
105 + pid: ++pid,
106 + tid: ++tid,
107 + ts: ++startTime,
108 + ...data,
109 + };
110 + }
111 +
112 + function createUserTimingData(sampleMarks) {
113 + const cpuProfilerSample = createUserTimingEntry({
114 + args: {data: {startTime: ++startTime}},
115 + cat: 'disabled-by-default-v8.cpu_profiler',
116 + id: '0x1',
117 + name: 'Profile',
118 + ph: 'P',
119 + });
120 +
121 + const randomSample = createUserTimingEntry({
122 + dur: 100,
123 + tdur: 200,
124 + ph: 'X',
125 + cat: 'disabled-by-default-devtools.timeline',
126 + name: 'RunTask',
127 + args: {},
128 + });
129 +
130 + const userTimingData = [cpuProfilerSample, randomSample];
131 +
132 + sampleMarks.forEach(markName => {
133 + userTimingData.push({
134 + pid: ++pid,
135 + tid: ++tid,
136 + ts: ++startTime,
137 + args: {data: {navigationId: 'fake-navigation-id'}},
138 + cat: 'blink.user_timing',
139 + name: markName,
140 + ph: 'R',
141 + });
142 + });
143 +
144 + return userTimingData;
145 + }
146 +
147 + beforeEach(() => {
148 + jest.resetModules();
149 +
150 + polyfillJSDomUserTiming();
151 +
152 + React = require('react');
153 + ReactDOM = require('react-dom');
154 +
155 + const TestUtils = require('react-dom/test-utils');
156 + act = TestUtils.act;
157 +
158 + tid = 0;
159 + pid = 0;
160 + startTime = 0;
161 + });
162 +
163 + afterEach(() => {
164 + // Verify all logged marks also get cleared.
165 + expect(marks).toHaveLength(0);
166 +
167 + delete global.performance;
168 + });
169 +
170 + it('should throw given an empty timeline', () => {
171 + expect(() => preprocessData([])).toThrow();
172 + });
173 +
174 + it('should throw given a timeline with no Profile event', () => {
175 + const randomSample = createUserTimingEntry({
176 + dur: 100,
177 + tdur: 200,
178 + ph: 'X',
179 + cat: 'disabled-by-default-devtools.timeline',
180 + name: 'RunTask',
181 + args: {},
182 + });
183 +
184 + expect(() => preprocessData([randomSample])).toThrow();
185 + });
186 +
187 + it('should return empty data given a timeline with no React scheduling profiling marks', () => {
188 + const cpuProfilerSample = createUserTimingEntry({
189 + args: {data: {startTime: ++startTime}},
190 + cat: 'disabled-by-default-v8.cpu_profiler',
191 + id: '0x1',
192 + name: 'Profile',
193 + ph: 'P',
194 + });
195 +
196 + const randomSample = createUserTimingEntry({
197 + dur: 100,
198 + tdur: 200,
199 + ph: 'X',
200 + cat: 'disabled-by-default-devtools.timeline',
201 + name: 'RunTask',
202 + args: {},
203 + });
204 +
205 + expect(preprocessData([cpuProfilerSample, randomSample])).toStrictEqual({
206 + duration: 0.002,
207 + events: [],
208 + flamechart: [],
209 + measures: [],
210 + otherUserTimingMarks: [],
211 + startTime: 1,
212 + });
213 + });
214 +
215 + // NOTE This test doesn't have to be gated because it has hard-coded profiler samples.
216 + it('should process legacy data format (before lane labels were added)', () => {
217 + const cpuProfilerSample = createUserTimingEntry({
218 + args: {data: {startTime: ++startTime}},
219 + cat: 'disabled-by-default-v8.cpu_profiler',
220 + id: '0x1',
221 + name: 'Profile',
222 + ph: 'P',
223 + });
224 +
225 + expect(
226 + // Data below is hard-coded based on an older profile sample.
227 + // Should be fine since this is explicitly a legacy-format test.
228 + preprocessData([
229 + cpuProfilerSample,
230 + createUserTimingEntry({
231 + cat: 'blink.user_timing',
232 + name: '--schedule-render-512-',
233 + }),
234 + createUserTimingEntry({
235 + cat: 'blink.user_timing',
236 + name: '--render-start-512',
237 + }),
238 + createUserTimingEntry({
239 + cat: 'blink.user_timing',
240 + name: '--render-stop',
241 + }),
242 + createUserTimingEntry({
243 + cat: 'blink.user_timing',
244 + name: '--commit-start-512',
245 + }),
246 + createUserTimingEntry({
247 + cat: 'blink.user_timing',
248 + name: '--layout-effects-start-512',
249 + }),
250 + createUserTimingEntry({
251 + cat: 'blink.user_timing',
252 + name: '--layout-effects-stop',
253 + }),
254 + createUserTimingEntry({
255 + cat: 'blink.user_timing',
256 + name: '--commit-stop',
257 + }),
258 + ]),
259 + ).toStrictEqual({
260 + duration: 0.008,
261 + events: [
262 + {
263 + componentStack: '',
264 + laneLabels: [],
265 + lanes: [9],
266 + timestamp: 0.002,
267 + type: 'schedule-render',
268 + },
269 + ],
270 + flamechart: [],
271 + measures: [
272 + {
273 + batchUID: 0,
274 + depth: 0,
275 + duration: 0.005,
276 + laneLabels: [],
277 + lanes: [9],
278 + timestamp: 0.003,
279 + type: 'render-idle',
280 + },
281 + {
282 + batchUID: 0,
283 + depth: 0,
284 + duration: 0.001,
285 + laneLabels: [],
286 + lanes: [9],
287 + timestamp: 0.003,
288 + type: 'render',
289 + },
290 + {
291 + batchUID: 0,
292 + depth: 0,
293 + duration: 0.003,
294 + laneLabels: [],
295 + lanes: [9],
296 + timestamp: 0.005,
297 + type: 'commit',
298 + },
299 + {
300 + batchUID: 0,
301 + depth: 1,
302 + duration: 0.001,
303 + laneLabels: [],
304 + lanes: [9],
305 + timestamp: 0.006,
306 + type: 'layout-effects',
307 + },
308 + ],
309 + otherUserTimingMarks: [],
310 + startTime: 1,
311 + });
312 + });
313 +
314 + // @gate enableSchedulingProfiler
315 + it('should process a sample legacy render sequence', () => {
316 + ReactDOM.render(<div />, document.createElement('div'));
317 +
318 + const reactVersion = require('shared/ReactVersion').default;
319 +
320 + const userTimingData = createUserTimingData(clearedMarks);
321 + expect(preprocessData(userTimingData)).toStrictEqual({
322 + duration: 0.011,
323 + events: [
324 + {
325 + componentStack: '',
326 + laneLabels: ['Sync'],
327 + lanes: [0],
328 + timestamp: 0.005,
329 + type: 'schedule-render',
330 + },
331 + ],
332 + flamechart: [],
333 + measures: [
334 + {
335 + batchUID: 0,
336 + depth: 0,
337 + duration: 0.004999999999999999,
338 + laneLabels: ['Sync'],
339 + lanes: [0],
340 + timestamp: 0.006,
341 + type: 'render-idle',
342 + },
343 + {
344 + batchUID: 0,
345 + depth: 0,
346 + duration: 0.001,
347 + laneLabels: ['Sync'],
348 + lanes: [0],
349 + timestamp: 0.006,
350 + type: 'render',
351 + },
352 + {
353 + batchUID: 0,
354 + depth: 0,
355 + duration: 0.002999999999999999,
356 + laneLabels: ['Sync'],
357 + lanes: [0],
358 + timestamp: 0.008,
359 + type: 'commit',
360 + },
361 + {
362 + batchUID: 0,
363 + depth: 1,
364 + duration: 0.0010000000000000009,
365 + laneLabels: ['Sync'],
366 + lanes: [0],
367 + timestamp: 0.009,
368 + type: 'layout-effects',
369 + },
370 + ],
371 + otherUserTimingMarks: [
372 + {
373 + name: '__v3',
374 + timestamp: 0.003,
375 + },
376 + {
377 + name: `--react-init-${reactVersion}`,
378 + timestamp: 0.004,
379 + },
380 + ],
381 + startTime: 1,
382 + });
383 + });
384 +
385 + // @gate experimental && enableSchedulingProfiler
386 + it('should process a sample createRoot render sequence', () => {
387 + function App() {
388 + const [didMount, setDidMount] = React.useState(false);
389 + React.useEffect(() => {
390 + if (!didMount) {
391 + setDidMount(true);
392 + }
393 + });
394 + return true;
395 + }
396 +
397 + const root = ReactDOM.createRoot(document.createElement('div'));
398 + act(() => root.render(<App />));
399 +
400 + const userTimingData = createUserTimingData(clearedMarks);
401 + expect(preprocessData(userTimingData)).toStrictEqual({
402 + duration: 0.022,
403 + events: [
404 + {
405 + componentStack: '',
406 + laneLabels: ['Default'],
407 + lanes: [7],
408 + timestamp: 0.005,
409 + type: 'schedule-render',
410 + },
411 + {
412 + componentName: 'App',
413 + componentStack: '',
414 + isCascading: false,
415 + laneLabels: ['Default'],
416 + lanes: [7],
417 + timestamp: 0.013,
418 + type: 'schedule-state-update',
419 + },
420 + ],
421 + flamechart: [],
422 + measures: [
423 + {
424 + batchUID: 0,
425 + depth: 0,
426 + duration: 0.004999999999999999,
427 + laneLabels: ['Default'],
428 + lanes: [7],
429 + timestamp: 0.006,
430 + type: 'render-idle',
431 + },
432 + {
433 + batchUID: 0,
434 + depth: 0,
435 + duration: 0.001,
436 + laneLabels: ['Default'],
437 + lanes: [7],
438 + timestamp: 0.006,
439 + type: 'render',
440 + },
441 + {
442 + batchUID: 0,
443 + depth: 0,
444 + duration: 0.002999999999999999,
445 + laneLabels: ['Default'],
446 + lanes: [7],
447 + timestamp: 0.008,
448 + type: 'commit',
449 + },
450 + {
451 + batchUID: 0,
452 + depth: 1,
453 + duration: 0.0010000000000000009,
454 + laneLabels: ['Default'],
455 + lanes: [7],
456 + timestamp: 0.009,
457 + type: 'layout-effects',
458 + },
459 + {
460 + batchUID: 0,
461 + depth: 0,
462 + duration: 0.002,
463 + laneLabels: ['Default'],
464 + lanes: [7],
465 + timestamp: 0.012,
466 + type: 'passive-effects',
467 + },
468 + {
469 + batchUID: 1,
470 + depth: 0,
471 + duration: 0.005000000000000001,
472 + laneLabels: ['Default'],
473 + lanes: [7],
474 + timestamp: 0.015,
475 + type: 'render-idle',
476 + },
477 + {
478 + batchUID: 1,
479 + depth: 0,
480 + duration: 0.0010000000000000009,
481 + laneLabels: ['Default'],
482 + lanes: [7],
483 + timestamp: 0.015,
484 + type: 'render',
485 + },
486 + {
487 + batchUID: 1,
488 + depth: 0,
489 + duration: 0.002999999999999999,
490 + laneLabels: ['Default'],
491 + lanes: [7],
492 + timestamp: 0.017,
493 + type: 'commit',
494 + },
495 + {
496 + batchUID: 1,
497 + depth: 1,
498 + duration: 0.0010000000000000009,
499 + laneLabels: ['Default'],
500 + lanes: [7],
501 + timestamp: 0.018,
502 + type: 'layout-effects',
503 + },
504 + {
505 + batchUID: 1,
506 + depth: 0,
507 + duration: 0.0009999999999999974,
508 + laneLabels: ['Default'],
509 + lanes: [7],
510 + timestamp: 0.021,
511 + type: 'passive-effects',
512 + },
513 + ],
514 + otherUserTimingMarks: [
515 + {
516 + name: '__v3',
517 + timestamp: 0.003,
518 + },
519 + {
520 + name: '--react-init-17.0.2',
521 + timestamp: 0.004,
522 + },
523 + ],
524 + startTime: 1,
525 + });
526 + });
527 +
528 + // @gate enableSchedulingProfiler
529 + it('should error if events and measures are incomplete', () => {
530 + const container = document.createElement('div');
531 + ReactDOM.render(<div />, container);
532 +
533 + const invalidMarks = clearedMarks.filter(
534 + mark => !mark.includes('render-stop'),
535 + );
536 + const invalidUserTimingData = createUserTimingData(invalidMarks);
537 +
538 + const error = spyOnDevAndProd(console, 'error');
539 + preprocessData(invalidUserTimingData);
540 + expect(error).toHaveBeenCalled();
541 + });
542 +
543 + // @gate enableSchedulingProfiler
544 + it('should error if work is completed without being started', () => {
545 + const container = document.createElement('div');
546 + ReactDOM.render(<div />, container);
547 +
548 + const invalidMarks = clearedMarks.filter(
549 + mark => !mark.includes('render-start'),
550 + );
551 + const invalidUserTimingData = createUserTimingData(invalidMarks);
552 +
553 + const error = spyOnDevAndProd(console, 'error');
554 + preprocessData(invalidUserTimingData);
555 + expect(error).toHaveBeenCalled();
556 + });
557 +
558 + it('should populate other user timing marks', () => {
559 + const userTimingData = createUserTimingData([]);
560 + userTimingData.push(
561 + createUserTimingEntry({
562 + args: {},
563 + cat: 'blink.user_timing',
564 + id: '0xcdf75f7c',
565 + name: 'VCWithoutImage: root',
566 + ph: 'n',
567 + scope: 'blink.user_timing',
568 + }),
569 + );
570 + userTimingData.push(
571 + createUserTimingEntry({
572 + cat: 'blink.user_timing',
573 + name: '--a-mark-that-looks-like-one-of-ours',
574 + ph: 'R',
575 + }),
576 + );
577 + userTimingData.push(
578 + createUserTimingEntry({
579 + cat: 'blink.user_timing',
580 + name: 'Some other mark',
581 + ph: 'R',
582 + }),
583 + );
584 +
585 + expect(preprocessData(userTimingData).otherUserTimingMarks).toStrictEqual([
586 + {
587 + name: 'VCWithoutImage: root',
588 + timestamp: 0.003,
589 + },
590 + {
591 + name: '--a-mark-that-looks-like-one-of-ours',
592 + timestamp: 0.004,
593 + },
594 + {
595 + name: 'Some other mark',
596 + timestamp: 0.005,
597 + },
598 + ]);
599 + });
600 +
601 + // TODO: Add test for flamechart parsing
602 +});
packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.js deleted
-352
@@ -1,352 +0,0 @@
1 -/**
2 - * Copyright (c) Facebook, Inc. and its affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - */
7 -
8 -'use strict';
9 -
10 -import preprocessData, {
11 - getLanesFromTransportDecimalBitmask,
12 -} from '../preprocessData';
13 -import {REACT_TOTAL_NUM_LANES} from '../../constants';
14 -
15 -// Disable quotes rule in the whole file as we paste raw JSON as test inputs and
16 -// Prettier will already format the remaining quotes.
17 -/* eslint-disable quotes */
18 -
19 -describe(getLanesFromTransportDecimalBitmask, () => {
20 - it('should return array of lane numbers from bitmask string', () => {
21 - expect(getLanesFromTransportDecimalBitmask('1')).toEqual([0]);
22 - expect(getLanesFromTransportDecimalBitmask('512')).toEqual([9]);
23 - expect(getLanesFromTransportDecimalBitmask('3')).toEqual([0, 1]);
24 - expect(getLanesFromTransportDecimalBitmask('1234')).toEqual([
25 - 1,
26 - 4,
27 - 6,
28 - 7,
29 - 10,
30 - ]); // 2 + 16 + 64 + 128 + 1024
31 - expect(
32 - getLanesFromTransportDecimalBitmask('1073741824'), // 0b1000000000000000000000000000000
33 - ).toEqual([30]);
34 - expect(
35 - getLanesFromTransportDecimalBitmask('2147483647'), // 0b1111111111111111111111111111111
36 - ).toEqual(Array.from(Array(31).keys()));
37 - });
38 -
39 - it('should return empty array if laneBitmaskString is not a bitmask', () => {
40 - expect(getLanesFromTransportDecimalBitmask('')).toEqual([]);
41 - expect(getLanesFromTransportDecimalBitmask('hello')).toEqual([]);
42 - expect(getLanesFromTransportDecimalBitmask('-1')).toEqual([]);
43 - expect(getLanesFromTransportDecimalBitmask('-0')).toEqual([]);
44 - });
45 -
46 - it('should ignore lanes outside REACT_TOTAL_NUM_LANES', () => {
47 - // Sanity check; this test may need to be updated when the no. of fiber
48 - // lanes are changed.
49 - expect(REACT_TOTAL_NUM_LANES).toBe(31);
50 -
51 - expect(
52 - getLanesFromTransportDecimalBitmask(
53 - '4294967297', // 2^32 + 1
54 - ),
55 - ).toEqual([0]);
56 - });
57 -});
58 -
59 -describe(preprocessData, () => {
60 - it('should throw given an empty timeline', () => {
61 - expect(() => preprocessData([])).toThrow();
62 - });
63 -
64 - it('should throw given a timeline with no Profile event', () => {
65 - expect(() =>
66 - // prettier-ignore
67 - preprocessData([
68 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--schedule-render-512-","ph":"R","pid":9312,"tid":10252,"ts":8994056569,"tts":1816966},
69 - ]),
70 - ).toThrow();
71 - });
72 -
73 - it('should return empty data given a timeline with no React scheduling profiling marks', () => {
74 - expect(
75 - // prettier-ignore
76 - preprocessData([
77 - {"args":{"data":{"startTime":8993778496}},"cat":"disabled-by-default-v8.cpu_profiler","id":"0x1","name":"Profile","ph":"P","pid":9312,"tid":10252,"ts":8993778520,"tts":1614266},
78 - {"pid":57632,"tid":38659,"ts":874860756135,"ph":"X","cat":"disabled-by-default-devtools.timeline","name":"RunTask","dur":18,"tdur":19,"tts":8700284918,"args":{}},
79 - {"pid":57632,"tid":38659,"ts":874860756158,"ph":"X","cat":"disabled-by-default-devtools.timeline","name":"RunTask","dur":30,"tdur":30,"tts":8700284941,"args":{}},
80 - {"pid":57632,"tid":38659,"ts":874860756192,"ph":"X","cat":"disabled-by-default-devtools.timeline","name":"RunTask","dur":21,"tdur":20,"tts":8700284976,"args":{}},
81 - {"pid":57632,"tid":38659,"ts":874860756216,"ph":"X","cat":"disabled-by-default-devtools.timeline","name":"RunTask","dur":6,"tdur":5,"tts":8700285000,"args":{}},
82 - {"pid":57632,"tid":38659,"ts":874860756224,"ph":"X","cat":"disabled-by-default-devtools.timeline","name":"RunTask","dur":7,"tdur":6,"tts":8700285008,"args":{}},
83 - {"pid":57632,"tid":38659,"ts":874860756233,"ph":"X","cat":"disabled-by-default-devtools.timeline","name":"RunTask","dur":5,"tdur":4,"tts":8700285017,"args":{}},
84 - ]),
85 - ).toEqual({
86 - startTime: 8993778496,
87 - duration: 865866977.737,
88 - events: [],
89 - measures: [],
90 - flamechart: [],
91 - otherUserTimingMarks: [],
92 - });
93 - });
94 -
95 - it('should error if events and measures are incomplete', () => {
96 - const error = spyOnDevAndProd(console, 'error');
97 - // prettier-ignore
98 - preprocessData([
99 - {"args":{"data":{"startTime":8993778496}},"cat":"disabled-by-default-v8.cpu_profiler","id":"0x1","name":"Profile","ph":"P","pid":9312,"tid":10252,"ts":8993778520,"tts":1614266},
100 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--render-start-8","ph":"R","pid":1852,"tid":12484,"ts":42351664678,"tts":1512475},
101 - ]);
102 - expect(error).toHaveBeenCalled();
103 - });
104 -
105 - it('should error if work is completed without being started', () => {
106 - const error = spyOnDevAndProd(console, 'error');
107 - // prettier-ignore
108 - preprocessData([
109 - {"args":{"data":{"startTime":8993778496}},"cat":"disabled-by-default-v8.cpu_profiler","id":"0x1","name":"Profile","ph":"P","pid":9312,"tid":10252,"ts":8993778520,"tts":1614266},
110 - {"args":{"data":{"navigationId":"E082C30FBDA3ACEE0E7B5FD75F8B7F0D"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":17232,"tid":13628,"ts":264686513020,"tts":4082554},
111 - ]);
112 - expect(error).toHaveBeenCalled();
113 - });
114 -
115 - it('should process complete set of events (page load sample data)', () => {
116 - expect(
117 - // prettier-ignore
118 - preprocessData([
119 - {"args":{"data":{"documentLoaderURL":"https://concurrent-demo.now.sh/","isLoadingMainFrame":true,"navigationId":"43BC238A4FB7548146D3CD739C9C9434"},"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing","name":"navigationStart","ph":"R","pid":9312,"tid":10252,"ts":8993749139,"tts":1646191},
120 - {"args":{"data":{"startTime":8993778496}},"cat":"disabled-by-default-v8.cpu_profiler","id":"0x1","name":"Profile","ph":"P","pid":9312,"tid":10252,"ts":8993778520,"tts":1614266},
121 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing","name":"fetchStart","ph":"R","pid":9312,"tid":10252,"ts":8993751576,"tts":1646197},
122 - {"args":{},"cat":"blink.user_timing","name":"requestStart","ph":"R","pid":9312,"tid":10252,"ts":8993757325,"tts":1612760},
123 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing","name":"responseEnd","ph":"R","pid":9312,"tid":10252,"ts":8993762841,"tts":1652151},
124 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing","name":"unloadEventStart","ph":"R","pid":9312,"tid":10252,"ts":8993777756,"tts":1646416},
125 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing","name":"unloadEventEnd","ph":"R","pid":9312,"tid":10252,"ts":8993818104,"tts":1646419},
126 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing,rail","name":"domLoading","ph":"R","pid":9312,"tid":10252,"ts":8993820215,"tts":1647488},
127 - {"args":{},"cat":"blink.user_timing","name":"requestStart","ph":"R","pid":9312,"tid":10252,"ts":8993886145,"tts":1771277},
128 - {"args":{},"cat":"blink.user_timing","name":"requestStart","ph":"R","pid":9312,"tid":10252,"ts":8993886881,"tts":1778953},
129 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--schedule-render-512-","ph":"R","pid":9312,"tid":10252,"ts":8994056569,"tts":1816966},
130 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing,rail","name":"domInteractive","ph":"R","pid":9312,"tid":10252,"ts":8994058638,"tts":1818851},
131 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing,rail","name":"domContentLoadedEventStart","ph":"R","pid":9312,"tid":10252,"ts":8994058898,"tts":1819078},
132 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing,rail","name":"domContentLoadedEventEnd","ph":"R","pid":9312,"tid":10252,"ts":8994060045,"tts":1820100},
133 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994063789,"tts":1823183},
134 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994069024,"tts":1826507},
135 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994076204,"tts":1830657},
136 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994084372,"tts":1837590},
137 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing,rail","name":"domComplete","ph":"R","pid":9312,"tid":10252,"ts":8994085517,"tts":1838615},
138 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing","name":"loadEventStart","ph":"R","pid":9312,"tid":10252,"ts":8994085552,"tts":1838649},
139 - {"args":{"frame":"FD65D9AFD04B1295CEA36B883F0FA82F"},"cat":"blink.user_timing","name":"loadEventEnd","ph":"R","pid":9312,"tid":10252,"ts":8994086738,"tts":1839690},
140 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994088953,"tts":1840749},
141 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994093942,"tts":1844455},
142 - {"args":{},"cat":"blink.user_timing","name":"requestStart","ph":"R","pid":9312,"tid":10252,"ts":8994119825,"tts":1877483},
143 - {"args":{},"cat":"blink.user_timing","name":"requestStart","ph":"R","pid":9312,"tid":10252,"ts":8994122516,"tts":1886344},
144 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994136263,"tts":1871212},
145 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994142733,"tts":1875838},
146 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994149982,"tts":1880208},
147 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994156615,"tts":1885309},
148 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994163546,"tts":1887453},
149 - {"args":{},"cat":"blink.user_timing","name":"requestStart","ph":"R","pid":9312,"tid":10252,"ts":8994166081,"tts":1895751},
150 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994173436,"tts":1894442},
151 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994176556,"tts":1897176},
152 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994184415,"tts":1904263},
153 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994185162,"tts":1904938},
154 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994192423,"tts":1910624},
155 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994192714,"tts":1910872},
156 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994200415,"tts":1917859},
157 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994200637,"tts":1918062},
158 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994208430,"tts":1924894},
159 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994208681,"tts":1925124},
160 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994216388,"tts":1932117},
161 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994218048,"tts":1933622},
162 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994225455,"tts":1940076},
163 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994225790,"tts":1940391},
164 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994233439,"tts":1947224},
165 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994233711,"tts":1947473},
166 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994241447,"tts":1954160},
167 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994241755,"tts":1954426},
168 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994249451,"tts":1961213},
169 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994249743,"tts":1961494},
170 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994257444,"tts":1968141},
171 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994257858,"tts":1968525},
172 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994265413,"tts":1975172},
173 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994265691,"tts":1975416},
174 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994273481,"tts":1981826},
175 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994273850,"tts":1982112},
176 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994281467,"tts":1988537},
177 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994282202,"tts":1988894},
178 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994289444,"tts":1994103},
179 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994291602,"tts":1995165},
180 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994299421,"tts":2000342},
181 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994300163,"tts":2001009},
182 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994309433,"tts":2005662},
183 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994309681,"tts":2005897},
184 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994317439,"tts":2012641},
185 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994317709,"tts":2012890},
186 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994325444,"tts":2019235},
187 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994325719,"tts":2019477},
188 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994333449,"tts":2026367},
189 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994333730,"tts":2026617},
190 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994341427,"tts":2033147},
191 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994341728,"tts":2033411},
192 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994349443,"tts":2040163},
193 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994349708,"tts":2040409},
194 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994357469,"tts":2047136},
195 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994357820,"tts":2047465},
196 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994365438,"tts":2054203},
197 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994365697,"tts":2054434},
198 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994373435,"tts":2061259},
199 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994373705,"tts":2061502},
200 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994381444,"tts":2068300},
201 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994381690,"tts":2068529},
202 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994389422,"tts":2075272},
203 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994389708,"tts":2075518},
204 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994397421,"tts":2082156},
205 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994398070,"tts":2082726},
206 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994405440,"tts":2088860},
207 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994405684,"tts":2089091},
208 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994413420,"tts":2095780},
209 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994413689,"tts":2096021},
210 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994421418,"tts":2102791},
211 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994421702,"tts":2103047},
212 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994429611,"tts":2110142},
213 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994429835,"tts":2110349},
214 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994436841,"tts":2115594},
215 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994437451,"tts":2116087},
216 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994437941,"tts":2116287},
217 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-1-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994439235,"tts":2117153},
218 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-2-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994441050,"tts":2118088},
219 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994441951,"tts":2118783},
220 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994442698,"tts":2119371},
221 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994443276,"tts":2119875},
222 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994443448,"tts":2120040},
223 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994445176,"tts":2121499},
224 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-1-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994445697,"tts":2121968},
225 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-2-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994446236,"tts":2122460},
226 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994446778,"tts":2122951},
227 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994447344,"tts":2123444},
228 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-yield","ph":"R","pid":9312,"tid":10252,"ts":8994449037,"tts":2124925},
229 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994449280,"tts":2125142},
230 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at SuspenseList\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994449831,"tts":2125639},
231 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":9312,"tid":10252,"ts":8994450864,"tts":2126555},
232 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994451820,"tts":2127417},
233 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-start-512","ph":"R","pid":9312,"tid":10252,"ts":8994455732,"tts":2130777},
234 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--schedule-state-update-1-ForceUpdateDemo_ForceUpdateDemo-\n at ForceUpdateDemo_ForceUpdateDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:18:98)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8994457934,"tts":2132671},
235 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":9312,"tid":10252,"ts":8994458421,"tts":2133089},
236 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-1","ph":"R","pid":9312,"tid":10252,"ts":8994462600,"tts":2136847},
237 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":9312,"tid":10252,"ts":8994464817,"tts":2138817},
238 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-start-1","ph":"R","pid":9312,"tid":10252,"ts":8994464844,"tts":2138843},
239 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-start-1","ph":"R","pid":9312,"tid":10252,"ts":8994465763,"tts":2139664},
240 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":9312,"tid":10252,"ts":8994465784,"tts":2139686},
241 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":9312,"tid":10252,"ts":8994466156,"tts":2140023},
242 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":9312,"tid":10252,"ts":8994466372,"tts":2140208},
243 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-1-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995573418,"tts":2205582},
244 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-1-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995573870,"tts":2205980},
245 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-1024","ph":"R","pid":9312,"tid":10252,"ts":8995574538,"tts":2206568},
246 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995575662,"tts":2207534},
247 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-2-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995576307,"tts":2208142},
248 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995576659,"tts":2208445},
249 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995577001,"tts":2208736},
250 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":9312,"tid":10252,"ts":8995577971,"tts":2209602},
251 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-start-1024","ph":"R","pid":9312,"tid":10252,"ts":8995578068,"tts":2209689},
252 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-start-1024","ph":"R","pid":9312,"tid":10252,"ts":8995580101,"tts":2211495},
253 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":9312,"tid":10252,"ts":8995580122,"tts":2211515},
254 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":9312,"tid":10252,"ts":8995580657,"tts":2211995},
255 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-2-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995644745,"tts":2217336},
256 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-2-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995645038,"tts":2217571},
257 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-2-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995645354,"tts":2217861},
258 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-2048","ph":"R","pid":9312,"tid":10252,"ts":8995645494,"tts":2217999},
259 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995646312,"tts":2218721},
260 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995647134,"tts":2219450},
261 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995647462,"tts":2219740},
262 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":9312,"tid":10252,"ts":8995648162,"tts":2220335},
263 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-start-2048","ph":"R","pid":9312,"tid":10252,"ts":8995648191,"tts":2220363},
264 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-start-2048","ph":"R","pid":9312,"tid":10252,"ts":8995649260,"tts":2221320},
265 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":9312,"tid":10252,"ts":8995649280,"tts":2221340},
266 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":9312,"tid":10252,"ts":8995649611,"tts":2221636},
267 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995758769,"tts":2228839},
268 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995759018,"tts":2229064},
269 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995759442,"tts":2229424},
270 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-3-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995759660,"tts":2229627},
271 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-4096","ph":"R","pid":9312,"tid":10252,"ts":8995759857,"tts":2229803},
272 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995760575,"tts":2230456},
273 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8995761666,"tts":2231399},
274 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":9312,"tid":10252,"ts":8995762296,"tts":2231965},
275 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-start-4096","ph":"R","pid":9312,"tid":10252,"ts":8995762367,"tts":2232017},
276 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-start-4096","ph":"R","pid":9312,"tid":10252,"ts":8995763427,"tts":2232966},
277 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":9312,"tid":10252,"ts":8995763454,"tts":2232993},
278 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":9312,"tid":10252,"ts":8995763625,"tts":2233154},
279 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996158083,"tts":2252466},
280 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996158391,"tts":2252730},
281 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996158738,"tts":2253038},
282 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996158983,"tts":2253239},
283 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-4-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996159231,"tts":2253447},
284 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-8192","ph":"R","pid":9312,"tid":10252,"ts":8996159465,"tts":2253624},
285 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-suspend-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996160268,"tts":2254312},
286 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":9312,"tid":10252,"ts":8996161775,"tts":2255670},
287 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-start-8192","ph":"R","pid":9312,"tid":10252,"ts":8996161834,"tts":2255716},
288 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-start-8192","ph":"R","pid":9312,"tid":10252,"ts":8996163031,"tts":2256754},
289 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":9312,"tid":10252,"ts":8996163051,"tts":2256773},
290 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":9312,"tid":10252,"ts":8996163355,"tts":2257045},
291 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996357682,"tts":2267920},
292 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996357983,"tts":2268179},
293 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at SuspenseList\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996358231,"tts":2268389},
294 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996358538,"tts":2268679},
295 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996358786,"tts":2268867},
296 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996359042,"tts":2269066},
297 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--suspense-resolved-0-ResourceButton-\n at ResourceButton (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:295)\n at Suspense\n at div\n at div\n at SuspenseDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:36:713)\n at App","ph":"R","pid":9312,"tid":10252,"ts":8996359296,"tts":2269264},
298 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-start-16384","ph":"R","pid":9312,"tid":10252,"ts":8996359448,"tts":2269412},
299 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":9312,"tid":10252,"ts":8996362873,"tts":2272363},
300 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-start-16384","ph":"R","pid":9312,"tid":10252,"ts":8996362944,"tts":2272420},
301 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-start-16384","ph":"R","pid":9312,"tid":10252,"ts":8996364618,"tts":2273869},
302 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":9312,"tid":10252,"ts":8996364645,"tts":2273895},
303 - {"args":{"data":{"navigationId":"43BC238A4FB7548146D3CD739C9C9434"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":9312,"tid":10252,"ts":8996365391,"tts":2274547},
304 - ]),
305 - ).toMatchSnapshot();
306 - });
307 -
308 - it('should process forced update event', () => {
309 - expect(
310 - // prettier-ignore
311 - preprocessData([
312 - {"args":{"data":{"startTime":40806924876}},"cat":"disabled-by-default-v8.cpu_profiler","id":"0x2","name":"Profile","ph":"P","pid":1852,"tid":12484,"ts":40806924880,"tts":996658},
313 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--schedule-forced-update-16-ForceUpdateDemo_ForceUpdateDemo-\n at ForceUpdateDemo_ForceUpdateDemo (https://concurrent-demo.now.sh/static/js/main.c9f122eb.chunk.js:18:98)\n at App","ph":"R","pid":1852,"tid":12484,"ts":40806988231,"tts":1037762},
314 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--render-start-16","ph":"R","pid":1852,"tid":12484,"ts":40806990146,"tts":1038890},
315 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--render-stop","ph":"R","pid":1852,"tid":12484,"ts":40806991123,"tts":1039401},
316 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--commit-start-16","ph":"R","pid":1852,"tid":12484,"ts":40806991170,"tts":1039447},
317 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--layout-effects-start-16","ph":"R","pid":1852,"tid":12484,"ts":40806992201,"tts":1040023},
318 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--layout-effects-stop","ph":"R","pid":1852,"tid":12484,"ts":40806992219,"tts":1040041},
319 - {"args":{"data":{"navigationId":"1065756F5FDAD64BE45CA86B0BBC1F8B"}},"cat":"blink.user_timing","name":"--commit-stop","ph":"R","pid":1852,"tid":12484,"ts":40806992337,"tts":1040149},
320 - ]),
321 - ).toMatchSnapshot();
322 - });
323 -
324 - it('should populate other user timing marks', () => {
325 - expect(
326 - // prettier-ignore
327 - preprocessData([
328 - {"args":{},"cat":"blink.user_timing","id":"0xcdf75f7c","name":"VCWithoutImage: root","ph":"n","pid":55132,"scope":"blink.user_timing","tid":775,"ts":458734963394},
329 - {"args":{"data":{"startTime":458738069897}},"cat":"disabled-by-default-v8.cpu_profiler","id":"0x4","name":"Profile","ph":"P","pid":55132,"tid":775,"ts":458738069898,"tts":27896428},
330 - {"args":{"data":{"navigationId":"B8774C733A75946C099FE21F8A0E8D38"}},"cat":"blink.user_timing","name":"--a-mark-that-looks-like-one-of-ours","ph":"R","pid":55132,"tid":775,"ts":458738256356,"tts":28082555},
331 - {"args":{"data":{"navigationId":"B8774C733A75946C099FE21F8A0E8D38"}},"cat":"blink.user_timing","name":"Some other mark","ph":"R","pid":55132,"tid":775,"ts":458738261491,"tts":28087691},
332 - ]).otherUserTimingMarks,
333 - ).toMatchInlineSnapshot(`
334 - Array [
335 - Object {
336 - "name": "VCWithoutImage: root",
337 - "timestamp": -3106.503,
338 - },
339 - Object {
340 - "name": "--a-mark-that-looks-like-one-of-ours",
341 - "timestamp": 186.459,
342 - },
343 - Object {
344 - "name": "Some other mark",
345 - "timestamp": 191.594,
346 - },
347 - ]
348 - `);
349 - });
350 -
351 - // TODO: Add test for flamechart parsing
352 -});
packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js
+34 -7
@@ -82,6 +82,7 @@ function markWorkStarted(
82 type: ReactMeasureType,
83 startTime: Milliseconds,
84 lanes: ReactLane[],
85 + laneLabels: Array<string>,
86 currentProfilerData: ReactProfilerData,
87 state: ProcessorState,
88 ) {
@@ -96,6 +97,7 @@ function markWorkStarted(
97 batchUID,
98 depth,
99 lanes,
100 + laneLabels,
101 timestamp: startTime,
102 duration: 0,
103 });
@@ -168,18 +170,20 @@ function processTimelineEvent(
170
171 // React Events - schedule
172 if (name.startsWith('--schedule-render-')) {
171 - const [laneBitmaskString, ...splitComponentStack] = name
173 + const [laneBitmaskString, laneLabels, ...splitComponentStack] = name
174 .substr(18)
175 .split('-');
176 currentProfilerData.events.push({
177 type: 'schedule-render',
178 lanes: getLanesFromTransportDecimalBitmask(laneBitmaskString),
179 + laneLabels: laneLabels ? laneLabels.split(',') : [],
180 componentStack: splitComponentStack.join('-'),
181 timestamp: startTime,
182 });
183 } else if (name.startsWith('--schedule-forced-update-')) {
184 const [
185 laneBitmaskString,
186 + laneLabels,
187 componentName,
188 ...splitComponentStack
189 ] = name.substr(25).split('-');
@@ -189,6 +193,7 @@ function processTimelineEvent(
193 currentProfilerData.events.push({
194 type: 'schedule-force-update',
195 lanes: getLanesFromTransportDecimalBitmask(laneBitmaskString),
196 + laneLabels: laneLabels ? laneLabels.split(',') : [],
197 componentName,
198 componentStack: splitComponentStack.join('-'),
199 timestamp: startTime,
@@ -197,6 +202,7 @@ function processTimelineEvent(
202 } else if (name.startsWith('--schedule-state-update-')) {
203 const [
204 laneBitmaskString,
205 + laneLabels,
206 componentName,
207 ...splitComponentStack
208 ] = name.substr(24).split('-');
@@ -206,6 +212,7 @@ function processTimelineEvent(
212 currentProfilerData.events.push({
213 type: 'schedule-state-update',
214 lanes: getLanesFromTransportDecimalBitmask(laneBitmaskString),
215 + laneLabels: laneLabels ? laneLabels.split(',') : [],
216 componentName,
217 componentStack: splitComponentStack.join('-'),
218 timestamp: startTime,
@@ -255,7 +262,7 @@ function processTimelineEvent(
262 state.nextRenderShouldGenerateNewBatchID = false;
263 state.batchUID = ((state.uidCounter++: any): BatchUID);
264 }
258 - const laneBitmaskString = name.substr(15);
265 + const [laneBitmaskString, laneLabels] = name.substr(15).split('-');
266 const lanes = getLanesFromTransportDecimalBitmask(laneBitmaskString);
267 throwIfIncomplete('render', state.measureStack);
268 if (getLastType(state.measureStack) !== 'render-idle') {
@@ -263,11 +270,19 @@ function processTimelineEvent(
270 'render-idle',
271 startTime,
272 lanes,
273 + laneLabels ? laneLabels.split(',') : [],
274 currentProfilerData,
275 state,
276 );
277 }
270 - markWorkStarted('render', startTime, lanes, currentProfilerData, state);
278 + markWorkStarted(
279 + 'render',
280 + startTime,
281 + lanes,
282 + laneLabels ? laneLabels.split(',') : [],
283 + currentProfilerData,
284 + state,
285 + );
286 } else if (
287 name.startsWith('--render-stop') ||
288 name.startsWith('--render-yield')
@@ -297,9 +312,16 @@ function processTimelineEvent(
312 // React Measures - commits
313 else if (name.startsWith('--commit-start-')) {
314 state.nextRenderShouldGenerateNewBatchID = true;
300 - const laneBitmaskString = name.substr(15);
315 + const [laneBitmaskString, laneLabels] = name.substr(15).split('-');
316 const lanes = getLanesFromTransportDecimalBitmask(laneBitmaskString);
302 - markWorkStarted('commit', startTime, lanes, currentProfilerData, state);
317 + markWorkStarted(
318 + 'commit',
319 + startTime,
320 + lanes,
321 + laneLabels ? laneLabels.split(',') : [],
322 + currentProfilerData,
323 + state,
324 + );
325 } else if (name.startsWith('--commit-stop')) {
326 markWorkCompleted(
327 'commit',
@@ -317,12 +339,13 @@ function processTimelineEvent(
339
340 // React Measures - layout effects
341 else if (name.startsWith('--layout-effects-start-')) {
320 - const laneBitmaskString = name.substr(23);
342 + const [laneBitmaskString, laneLabels] = name.substr(23).split('-');
343 const lanes = getLanesFromTransportDecimalBitmask(laneBitmaskString);
344 markWorkStarted(
345 'layout-effects',
346 startTime,
347 lanes,
348 + laneLabels ? laneLabels.split(',') : [],
349 currentProfilerData,
350 state,
351 );
@@ -337,12 +360,13 @@ function processTimelineEvent(
360
361 // React Measures - passive effects
362 else if (name.startsWith('--passive-effects-start-')) {
340 - const laneBitmaskString = name.substr(24);
363 + const [laneBitmaskString, laneLabels] = name.substr(24).split('-');
364 const lanes = getLanesFromTransportDecimalBitmask(laneBitmaskString);
365 markWorkStarted(
366 'passive-effects',
367 startTime,
368 lanes,
369 + laneLabels ? laneLabels.split(',') : [],
370 currentProfilerData,
371 state,
372 );
@@ -366,6 +390,9 @@ function processTimelineEvent(
390 // TODO: Begin user timing measure
391 } else if (ph === 'e') {
392 // TODO: End user timing measure
393 + } else if (ph === 'i' || ph === 'I') {
394 + // Instant events.
395 + // Note that the capital "I" is a deprecated value that exists in Chrome Canary traces.
396 } // eslint-disable-line brace-style
397
398 // Unrecognized event
packages/react-devtools-scheduling-profiler/src/types.js
+2
@@ -30,6 +30,7 @@ type BaseReactEvent = {|
30 type BaseReactScheduleEvent = {|
31 ...BaseReactEvent,
32 +lanes: ReactLane[],
33 + +laneLabels: string[],
34 |};
35 export type ReactScheduleRenderEvent = {|
36 ...BaseReactScheduleEvent,
@@ -86,6 +87,7 @@ export type BatchUID = number;
87 export type ReactMeasure = {|
88 +type: ReactMeasureType,
89 +lanes: ReactLane[],
90 + +laneLabels: string[],
91 +timestamp: Milliseconds,
92 +duration: Milliseconds,
93 +batchUID: BatchUID,
packages/react-devtools-scheduling-profiler/webpack.config.js
+2 -1
@@ -56,6 +56,7 @@ const config = {
56 __DEV__,
57 __PROFILE__: false,
58 __EXPERIMENTAL__: true,
59 + __VARIANT__: false,
60 'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
61 }),
62 new HtmlWebpackPlugin({
@@ -112,7 +113,7 @@ const config = {
113 if (shouldUseDevServer) {
114 config.devServer = {
115 hot: true,
115 - port: 8080,
116 + port: 8081,
117 clientLogLevel: 'warning',
118 stats: 'errors-only',
119 };
packages/react-reconciler/src/ReactFiberLane.new.js
+61 -4
@@ -36,7 +36,7 @@ export type Lane = number;
36 export type LaneMap<T> = Array<T>;
37
38 import invariant from 'shared/invariant';
39 -import {enableCache} from 'shared/ReactFeatureFlags';
39 +import {enableCache, enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
40
41 import {
42 ImmediatePriority as ImmediateSchedulerPriority,
@@ -73,7 +73,10 @@ const OffscreenLanePriority: LanePriority = 1;
73
74 export const NoLanePriority: LanePriority = 0;
75
76 -const TotalLanes = 31;
76 +// Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler.
77 +// If those values are changed that package should be rebuilt and redeployed.
78 +
79 +export const TotalLanes = 31;
80
81 export const NoLanes: Lanes = /* */ 0b0000000000000000000000000000000;
82 export const NoLane: Lane = /* */ 0b0000000000000000000000000000000;
@@ -82,10 +85,10 @@ export const SyncLane: Lane = /* */ 0b0000000000000000000
85 export const SyncBatchedLane: Lane = /* */ 0b0000000000000000000000000000010;
86
87 export const InputDiscreteHydrationLane: Lane = /* */ 0b0000000000000000000000000000100;
85 -const InputDiscreteLane: Lanes = /* */ 0b0000000000000000000000000001000;
88 +export const InputDiscreteLane: Lanes = /* */ 0b0000000000000000000000000001000;
89
90 const InputContinuousHydrationLane: Lane = /* */ 0b0000000000000000000000000010000;
88 -const InputContinuousLane: Lanes = /* */ 0b0000000000000000000000000100000;
91 +export const InputContinuousLane: Lanes = /* */ 0b0000000000000000000000000100000;
92
93 export const DefaultHydrationLane: Lane = /* */ 0b0000000000000000000000001000000;
94 export const DefaultLane: Lanes = /* */ 0b0000000000000000000000010000000;
@@ -124,6 +127,60 @@ const IdleLane: Lanes = /* */ 0b0100000000000000000
127
128 export const OffscreenLane: Lane = /* */ 0b1000000000000000000000000000000;
129
130 +// This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler)
131 +// It should be kept in sync with the Lanes values above.
132 +export function getLabelsForLanes(lanes: Lanes): Array<string> | void {
133 + if (enableSchedulingProfiler) {
134 + const labels = [];
135 + if (lanes & SyncLane) {
136 + labels.push('Sync');
137 + }
138 + if (lanes & SyncBatchedLane) {
139 + labels.push('SyncBatched');
140 + }
141 + if (lanes & InputDiscreteHydrationLane) {
142 + labels.push('InputDiscreteHydration');
143 + }
144 + if (lanes & InputDiscreteLane) {
145 + labels.push('InputDiscrete');
146 + }
147 + if (lanes & InputContinuousHydrationLane) {
148 + labels.push('InputContinuousHydration');
149 + }
150 + if (lanes & InputContinuousLane) {
151 + labels.push('InputContinuous');
152 + }
153 + if (lanes & DefaultHydrationLane) {
154 + labels.push('DefaultHydration');
155 + }
156 + if (lanes & DefaultLane) {
157 + labels.push('Default');
158 + }
159 + if (lanes & TransitionHydrationLane) {
160 + labels.push('TransitionHydration');
161 + }
162 + if (lanes & TransitionLanes) {
163 + labels.push('Transition(s)');
164 + }
165 + if (lanes & RetryLanes) {
166 + labels.push('Retry(s)');
167 + }
168 + if (lanes & SelectiveHydrationLane) {
169 + labels.push('SelectiveHydration');
170 + }
171 + if (lanes & IdleHydrationLane) {
172 + labels.push('IdleHydration');
173 + }
174 + if (lanes & IdleLane) {
175 + labels.push('Idle');
176 + }
177 + if (lanes & OffscreenLane) {
178 + labels.push('Offscreen');
179 + }
180 + return labels;
181 + }
182 +}
183 +
184 export const NoTimestamp = -1;
185
186 let currentUpdateLanePriority: LanePriority = NoLanePriority;
packages/react-reconciler/src/ReactFiberLane.old.js
+61 -4
@@ -36,7 +36,7 @@ export type Lane = number;
36 export type LaneMap<T> = Array<T>;
37
38 import invariant from 'shared/invariant';
39 -import {enableCache} from 'shared/ReactFeatureFlags';
39 +import {enableCache, enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
40
41 import {
42 ImmediatePriority as ImmediateSchedulerPriority,
@@ -73,7 +73,10 @@ const OffscreenLanePriority: LanePriority = 1;
73
74 export const NoLanePriority: LanePriority = 0;
75
76 -const TotalLanes = 31;
76 +// Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler.
77 +// If those values are changed that package should be rebuilt and redeployed.
78 +
79 +export const TotalLanes = 31;
80
81 export const NoLanes: Lanes = /* */ 0b0000000000000000000000000000000;
82 export const NoLane: Lane = /* */ 0b0000000000000000000000000000000;
@@ -82,10 +85,10 @@ export const SyncLane: Lane = /* */ 0b0000000000000000000
85 export const SyncBatchedLane: Lane = /* */ 0b0000000000000000000000000000010;
86
87 export const InputDiscreteHydrationLane: Lane = /* */ 0b0000000000000000000000000000100;
85 -const InputDiscreteLane: Lanes = /* */ 0b0000000000000000000000000001000;
88 +export const InputDiscreteLane: Lanes = /* */ 0b0000000000000000000000000001000;
89
90 const InputContinuousHydrationLane: Lane = /* */ 0b0000000000000000000000000010000;
88 -const InputContinuousLane: Lanes = /* */ 0b0000000000000000000000000100000;
91 +export const InputContinuousLane: Lanes = /* */ 0b0000000000000000000000000100000;
92
93 export const DefaultHydrationLane: Lane = /* */ 0b0000000000000000000000001000000;
94 export const DefaultLane: Lanes = /* */ 0b0000000000000000000000010000000;
@@ -124,6 +127,60 @@ const IdleLane: Lanes = /* */ 0b0100000000000000000
127
128 export const OffscreenLane: Lane = /* */ 0b1000000000000000000000000000000;
129
130 +// This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler)
131 +// It should be kept in sync with the Lanes values above.
132 +export function getLabelsForLanes(lanes: Lanes): Array<string> | void {
133 + if (enableSchedulingProfiler) {
134 + const labels = [];
135 + if (lanes & SyncLane) {
136 + labels.push('Sync');
137 + }
138 + if (lanes & SyncBatchedLane) {
139 + labels.push('SyncBatched');
140 + }
141 + if (lanes & InputDiscreteHydrationLane) {
142 + labels.push('InputDiscreteHydration');
143 + }
144 + if (lanes & InputDiscreteLane) {
145 + labels.push('InputDiscrete');
146 + }
147 + if (lanes & InputContinuousHydrationLane) {
148 + labels.push('InputContinuousHydration');
149 + }
150 + if (lanes & InputContinuousLane) {
151 + labels.push('InputContinuous');
152 + }
153 + if (lanes & DefaultHydrationLane) {
154 + labels.push('DefaultHydration');
155 + }
156 + if (lanes & DefaultLane) {
157 + labels.push('Default');
158 + }
159 + if (lanes & TransitionHydrationLane) {
160 + labels.push('TransitionHydration');
161 + }
162 + if (lanes & TransitionLanes) {
163 + labels.push('Transition(s)');
164 + }
165 + if (lanes & RetryLanes) {
166 + labels.push('Retry(s)');
167 + }
168 + if (lanes & SelectiveHydrationLane) {
169 + labels.push('SelectiveHydration');
170 + }
171 + if (lanes & IdleHydrationLane) {
172 + labels.push('IdleHydration');
173 + }
174 + if (lanes & IdleLane) {
175 + labels.push('Idle');
176 + }
177 + if (lanes & OffscreenLane) {
178 + labels.push('Offscreen');
179 + }
180 + return labels;
181 + }
182 +}
183 +
184 export const NoTimestamp = -1;
185
186 let currentUpdateLanePriority: LanePriority = NoLanePriority;
packages/react-reconciler/src/SchedulingProfiler.js
+19 -3
@@ -11,10 +11,20 @@ import type {Lane, Lanes} from './ReactFiberLane.old';
11 import type {Fiber} from './ReactInternalTypes';
12 import type {Wakeable} from 'shared/ReactTypes';
13
14 -import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
14 +import {
15 + enableNewReconciler,
16 + enableSchedulingProfiler,
17 +} from 'shared/ReactFeatureFlags';
18 import ReactVersion from 'shared/ReactVersion';
19 import getComponentName from 'shared/getComponentName';
20
21 +import {getLabelsForLanes as getLabelsForLanes_old} from 'react-reconciler/src/ReactFiberLane.old';
22 +import {getLabelsForLanes as getLabelsForLanes_new} from 'react-reconciler/src/ReactFiberLane.new';
23 +
24 +const getLabelsForLanes = enableNewReconciler
25 + ? getLabelsForLanes_new
26 + : getLabelsForLanes_old;
27 +
28 /**
29 * If performance exists and supports the subset of the User Timing API that we
30 * require.
@@ -49,8 +59,14 @@ if (enableSchedulingProfiler) {
59 }
60 }
61
52 -function formatLanes(laneOrLanes: Lane | Lanes): string {
53 - return ((laneOrLanes: any): number).toString();
62 +export function formatLanes(laneOrLanes: Lane | Lanes): string {
63 + let labels = getLabelsForLanes(laneOrLanes);
64 + if (labels != null) {
65 + labels = labels.sort().join(',');
66 + } else {
67 + labels = '';
68 + }
69 + return `${laneOrLanes}-${labels}`;
70 }
71
72 function markAndClear(name) {
packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
+87 -63
@@ -10,6 +10,7 @@
10
11 'use strict';
12
13 +// This test is *.internal so that it can import this shared file.
14 import ReactVersion from 'shared/ReactVersion';
15
16 describe('SchedulingProfiler', () => {
@@ -17,9 +18,11 @@ describe('SchedulingProfiler', () => {
18 let ReactTestRenderer;
19 let ReactNoop;
20 let Scheduler;
21 + let ReactFiberLane;
22
23 let clearedMarks;
24 let featureDetectionMarkName = null;
25 + let formatLanes;
26 let marks;
27
28 function createUserTimingPolyfill() {
@@ -76,6 +79,14 @@ describe('SchedulingProfiler', () => {
79 ReactNoop = require('react-noop-renderer');
80
81 Scheduler = require('scheduler');
82 +
83 + const SchedulingProfiler = require('react-reconciler/src/SchedulingProfiler');
84 + formatLanes = SchedulingProfiler.formatLanes;
85 +
86 + const ReactFeatureFlags = require('shared/ReactFeatureFlags');
87 + ReactFiberLane = ReactFeatureFlags.enableNewReconciler
88 + ? require('react-reconciler/src/ReactFiberLane.new')
89 + : require('react-reconciler/src/ReactFiberLane.old');
90 });
91
92 afterEach(() => {
@@ -85,9 +96,6 @@ describe('SchedulingProfiler', () => {
96 delete global.performance;
97 });
98
88 - // This is coupled to implementation
89 - const DEFAULT_LANE = 128;
90 -
99 // @gate !enableSchedulingProfiler
100 it('should not mark if enableSchedulingProfiler is false', () => {
101 ReactTestRenderer.create(<div />);
@@ -105,11 +113,11 @@ describe('SchedulingProfiler', () => {
113
114 expectMarksToEqual([
115 `--react-init-${ReactVersion}`,
108 - '--schedule-render-1',
109 - '--render-start-1',
116 + `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
117 + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
118 '--render-stop',
111 - '--commit-start-1',
112 - '--layout-effects-start-1',
119 + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
120 + `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`,
121 '--layout-effects-stop',
122 '--commit-stop',
123 ]);
@@ -121,7 +129,7 @@ describe('SchedulingProfiler', () => {
129
130 expectMarksToEqual([
131 `--react-init-${ReactVersion}`,
124 - `--schedule-render-${DEFAULT_LANE}`,
132 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
133 ]);
134
135 clearPendingMarks();
@@ -129,10 +137,10 @@ describe('SchedulingProfiler', () => {
137 expect(Scheduler).toFlushUntilNextPaint([]);
138
139 expectMarksToEqual([
132 - `--render-start-${DEFAULT_LANE}`,
140 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
141 '--render-stop',
134 - `--commit-start-${DEFAULT_LANE}`,
135 - `--layout-effects-start-${DEFAULT_LANE}`,
142 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
143 + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
144 '--layout-effects-stop',
145 '--commit-stop',
146 ]);
@@ -156,8 +164,8 @@ describe('SchedulingProfiler', () => {
164
165 expectMarksToEqual([
166 `--react-init-${ReactVersion}`,
159 - `--schedule-render-${DEFAULT_LANE}`,
160 - `--render-start-${DEFAULT_LANE}`,
167 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
168 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
169 '--render-yield',
170 ]);
171 });
@@ -177,12 +185,12 @@ describe('SchedulingProfiler', () => {
185
186 expectMarksToEqual([
187 `--react-init-${ReactVersion}`,
180 - '--schedule-render-1',
181 - '--render-start-1',
188 + `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
189 + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
190 '--suspense-suspend-0-Example',
191 '--render-stop',
184 - '--commit-start-1',
185 - '--layout-effects-start-1',
192 + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
193 + `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`,
194 '--layout-effects-stop',
195 '--commit-stop',
196 ]);
@@ -208,12 +216,12 @@ describe('SchedulingProfiler', () => {
216
217 expectMarksToEqual([
218 `--react-init-${ReactVersion}`,
211 - '--schedule-render-1',
212 - '--render-start-1',
219 + `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
220 + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
221 '--suspense-suspend-0-Example',
222 '--render-stop',
215 - '--commit-start-1',
216 - '--layout-effects-start-1',
223 + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
224 + `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`,
225 '--layout-effects-stop',
226 '--commit-stop',
227 ]);
@@ -240,7 +248,7 @@ describe('SchedulingProfiler', () => {
248
249 expectMarksToEqual([
250 `--react-init-${ReactVersion}`,
243 - `--schedule-render-${DEFAULT_LANE}`,
251 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
252 ]);
253
254 clearPendingMarks();
@@ -248,11 +256,11 @@ describe('SchedulingProfiler', () => {
256 expect(Scheduler).toFlushUntilNextPaint([]);
257
258 expectMarksToEqual([
251 - `--render-start-${DEFAULT_LANE}`,
259 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
260 '--suspense-suspend-0-Example',
261 '--render-stop',
254 - `--commit-start-${DEFAULT_LANE}`,
255 - `--layout-effects-start-${DEFAULT_LANE}`,
262 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
263 + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
264 '--layout-effects-stop',
265 '--commit-stop',
266 ]);
@@ -279,7 +287,7 @@ describe('SchedulingProfiler', () => {
287
288 expectMarksToEqual([
289 `--react-init-${ReactVersion}`,
282 - `--schedule-render-${DEFAULT_LANE}`,
290 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
291 ]);
292
293 clearPendingMarks();
@@ -287,11 +295,11 @@ describe('SchedulingProfiler', () => {
295 expect(Scheduler).toFlushUntilNextPaint([]);
296
297 expectMarksToEqual([
290 - `--render-start-${DEFAULT_LANE}`,
298 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
299 '--suspense-suspend-0-Example',
300 '--render-stop',
293 - `--commit-start-${DEFAULT_LANE}`,
294 - `--layout-effects-start-${DEFAULT_LANE}`,
301 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
302 + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
303 '--layout-effects-stop',
304 '--commit-stop',
305 ]);
@@ -318,7 +326,7 @@ describe('SchedulingProfiler', () => {
326
327 expectMarksToEqual([
328 `--react-init-${ReactVersion}`,
321 - `--schedule-render-${DEFAULT_LANE}`,
329 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
330 ]);
331
332 clearPendingMarks();
@@ -326,15 +334,15 @@ describe('SchedulingProfiler', () => {
334 expect(Scheduler).toFlushUntilNextPaint([]);
335
336 expectMarksToEqual([
329 - `--render-start-${DEFAULT_LANE}`,
337 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
338 '--render-stop',
331 - `--commit-start-${DEFAULT_LANE}`,
332 - `--layout-effects-start-${DEFAULT_LANE}`,
333 - '--schedule-state-update-1-Example',
339 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
340 + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
341 + `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`,
342 '--layout-effects-stop',
335 - '--render-start-1',
343 + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
344 '--render-stop',
337 - '--commit-start-1',
345 + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
346 '--commit-stop',
347 '--commit-stop',
348 ]);
@@ -355,7 +363,7 @@ describe('SchedulingProfiler', () => {
363
364 expectMarksToEqual([
365 `--react-init-${ReactVersion}`,
358 - `--schedule-render-${DEFAULT_LANE}`,
366 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
367 ]);
368
369 clearPendingMarks();
@@ -363,15 +371,17 @@ describe('SchedulingProfiler', () => {
371 expect(Scheduler).toFlushUntilNextPaint([]);
372
373 expectMarksToEqual([
366 - `--render-start-${DEFAULT_LANE}`,
374 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
375 '--render-stop',
368 - `--commit-start-${DEFAULT_LANE}`,
369 - `--layout-effects-start-${DEFAULT_LANE}`,
370 - '--schedule-forced-update-1-Example',
376 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
377 + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
378 + `--schedule-forced-update-${formatLanes(
379 + ReactFiberLane.SyncLane,
380 + )}-Example`,
381 '--layout-effects-stop',
372 - '--render-start-1',
382 + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
383 '--render-stop',
374 - '--commit-start-1',
384 + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
385 '--commit-stop',
386 '--commit-stop',
387 ]);
@@ -393,7 +403,7 @@ describe('SchedulingProfiler', () => {
403
404 expectMarksToEqual([
405 `--react-init-${ReactVersion}`,
396 - `--schedule-render-${DEFAULT_LANE}`,
406 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
407 ]);
408
409 clearPendingMarks();
@@ -402,7 +412,11 @@ describe('SchedulingProfiler', () => {
412 expect(Scheduler).toFlushUntilNextPaint([]);
413 }).toErrorDev('Cannot update during an existing state transition');
414
405 - expectMarksToContain(`--schedule-state-update-${DEFAULT_LANE}-Example`);
415 + expectMarksToContain(
416 + `--schedule-state-update-${formatLanes(
417 + ReactFiberLane.DefaultLane,
418 + )}-Example`,
419 + );
420 });
421
422 // @gate enableSchedulingProfiler
@@ -421,7 +435,7 @@ describe('SchedulingProfiler', () => {
435
436 expectMarksToEqual([
437 `--react-init-${ReactVersion}`,
424 - `--schedule-render-${DEFAULT_LANE}`,
438 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
439 ]);
440
441 clearPendingMarks();
@@ -430,7 +444,11 @@ describe('SchedulingProfiler', () => {
444 expect(Scheduler).toFlushUntilNextPaint([]);
445 }).toErrorDev('Cannot update during an existing state transition');
446
433 - expectMarksToContain(`--schedule-forced-update-${DEFAULT_LANE}-Example`);
447 + expectMarksToContain(
448 + `--schedule-forced-update-${formatLanes(
449 + ReactFiberLane.DefaultLane,
450 + )}-Example`,
451 + );
452 });
453
454 // @gate enableSchedulingProfiler
@@ -447,7 +465,7 @@ describe('SchedulingProfiler', () => {
465
466 expectMarksToEqual([
467 `--react-init-${ReactVersion}`,
450 - `--schedule-render-${DEFAULT_LANE}`,
468 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
469 ]);
470
471 clearPendingMarks();
@@ -455,15 +473,15 @@ describe('SchedulingProfiler', () => {
473 expect(Scheduler).toFlushUntilNextPaint([]);
474
475 expectMarksToEqual([
458 - `--render-start-${DEFAULT_LANE}`,
476 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
477 '--render-stop',
460 - `--commit-start-${DEFAULT_LANE}`,
461 - `--layout-effects-start-${DEFAULT_LANE}`,
462 - '--schedule-state-update-1-Example',
478 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
479 + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
480 + `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`,
481 '--layout-effects-stop',
464 - '--render-start-1',
482 + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
483 '--render-stop',
466 - '--commit-start-1',
484 + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
485 '--commit-stop',
486 '--commit-stop',
487 ]);
@@ -487,19 +505,21 @@ describe('SchedulingProfiler', () => {
505
506 expectMarksToEqual([
507 `--react-init-${ReactVersion}`,
490 - `--schedule-render-${DEFAULT_LANE}`,
491 - `--render-start-${DEFAULT_LANE}`,
508 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
509 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
510 '--render-stop',
493 - `--commit-start-${DEFAULT_LANE}`,
494 - `--layout-effects-start-${DEFAULT_LANE}`,
511 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
512 + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
513 '--layout-effects-stop',
514 '--commit-stop',
497 - `--passive-effects-start-${DEFAULT_LANE}`,
498 - `--schedule-state-update-${DEFAULT_LANE}-Example`,
515 + `--passive-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
516 + `--schedule-state-update-${formatLanes(
517 + ReactFiberLane.DefaultLane,
518 + )}-Example`,
519 '--passive-effects-stop',
500 - `--render-start-${DEFAULT_LANE}`,
520 + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
521 '--render-stop',
502 - `--commit-start-${DEFAULT_LANE}`,
522 + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
523 '--commit-stop',
524 ]);
525 });
@@ -518,6 +538,10 @@ describe('SchedulingProfiler', () => {
538 ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
539 });
540
521 - expectMarksToContain(`--schedule-state-update-${DEFAULT_LANE}-Example`);
541 + expectMarksToContain(
542 + `--schedule-state-update-${formatLanes(
543 + ReactFiberLane.DefaultLane,
544 + )}-Example`,
545 + );
546 });
547 });
packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js new
+179
@@ -0,0 +1,179 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @emails react-core
8 + */
9 +
10 +'use strict';
11 +
12 +// This test schedules work for as many lanes as we can (easily) using public APIs.
13 +// It will hopefully serve as a reminder to update getLabelsForLanes() when we update Lanes.
14 +// It's okay to delete any individual test in this file if the public API changes.
15 +describe('SchedulingProfiler labels', () => {
16 + let React;
17 + let ReactDOM;
18 + let ReactFiberLane;
19 +
20 + let act;
21 + let clearedMarks;
22 + let featureDetectionMarkName = null;
23 + let formatLanes;
24 + let marks;
25 +
26 + function polyfillJSDomUserTiming() {
27 + featureDetectionMarkName = null;
28 +
29 + clearedMarks = [];
30 + marks = [];
31 +
32 + // This is not a true polyfill, but it gives us enough to capture marks.
33 + // Reference: https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API
34 +
35 + // JSDom already implements global.performance and it can't be overridden.
36 + // However it only supports now() and timeOrigin() so we need to "upgrade it" in place.
37 +
38 + if (!global.performance) {
39 + global.performance = {};
40 + }
41 +
42 + global.performance.clearMarks = function clearMarks(markName) {
43 + clearedMarks.push(markName);
44 + marks = marks.filter(mark => mark !== markName);
45 + };
46 +
47 + global.performance.mark = function mark(markName, markOptions) {
48 + if (featureDetectionMarkName === null) {
49 + featureDetectionMarkName = markName;
50 + }
51 + marks.push(markName);
52 + if (markOptions != null) {
53 + // This is triggers the feature detection.
54 + markOptions.startTime++;
55 + }
56 + };
57 + }
58 +
59 + function dispatchAndSetCurrentEvent(element, event) {
60 + try {
61 + window.event = event;
62 + element.dispatchEvent(event);
63 + } finally {
64 + window.event = undefined;
65 + }
66 + }
67 +
68 + beforeEach(() => {
69 + jest.resetModules();
70 +
71 + polyfillJSDomUserTiming();
72 +
73 + React = require('react');
74 + ReactDOM = require('react-dom');
75 +
76 + const TestUtils = require('react-dom/test-utils');
77 + act = TestUtils.act;
78 +
79 + const SchedulingProfiler = require('react-reconciler/src/SchedulingProfiler');
80 + formatLanes = SchedulingProfiler.formatLanes;
81 +
82 + const ReactFeatureFlags = require('shared/ReactFeatureFlags');
83 + ReactFiberLane = ReactFeatureFlags.enableNewReconciler
84 + ? require('react-reconciler/src/ReactFiberLane.new')
85 + : require('react-reconciler/src/ReactFiberLane.old');
86 + });
87 +
88 + afterEach(() => {
89 + // Verify all logged marks also get cleared.
90 + expect(marks).toHaveLength(0);
91 +
92 + delete global.performance;
93 + });
94 +
95 + // @gate enableSchedulingProfiler
96 + it('regression test SyncLane', () => {
97 + ReactDOM.render(<div />, document.createElement('div'));
98 + expect(clearedMarks).toContain(
99 + `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
100 + );
101 + });
102 +
103 + // @gate experimental
104 + // @gate enableSchedulingProfiler
105 + it('regression test DefaultLane', () => {
106 + const container = document.createElement('div');
107 + const root = ReactDOM.createRoot(container);
108 +
109 + act(() => {
110 + root.render(<div />);
111 + expect(clearedMarks).toContain(
112 + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
113 + );
114 + });
115 + });
116 +
117 + // @gate experimental
118 + // @gate enableSchedulingProfiler
119 + // @gate !enableLegacyFBSupport
120 + it('regression test InputDiscreteLane', () => {
121 + const container = document.createElement('div');
122 + const root = ReactDOM.createRoot(container);
123 + const targetRef = React.createRef(null);
124 +
125 + function App() {
126 + const [count, setCount] = React.useState(0);
127 + const handleClick = () => {
128 + setCount(count + 1);
129 + };
130 + return <button ref={targetRef} onClick={handleClick} />;
131 + }
132 +
133 + act(() => {
134 + root.render(<App />);
135 + });
136 +
137 + clearedMarks.splice(0);
138 +
139 + act(() => {
140 + targetRef.current.click();
141 + });
142 + expect(clearedMarks).toContain(
143 + `--schedule-state-update-${formatLanes(
144 + ReactFiberLane.InputDiscreteLane,
145 + )}-App`,
146 + );
147 + });
148 +
149 + // @gate experimental
150 + // @gate enableSchedulingProfiler
151 + it('regression test InputContinuousLane', () => {
152 + const container = document.createElement('div');
153 + const root = ReactDOM.createRoot(container);
154 + const targetRef = React.createRef(null);
155 +
156 + function App() {
157 + const [count, setCount] = React.useState(0);
158 + const handleMouseOver = () => setCount(count + 1);
159 + return <div ref={targetRef} onMouseOver={handleMouseOver} />;
160 + }
161 +
162 + act(() => {
163 + root.render(<App />);
164 + });
165 +
166 + clearedMarks.splice(0);
167 +
168 + act(() => {
169 + const event = document.createEvent('MouseEvents');
170 + event.initEvent('mouseover', true, true);
171 + dispatchAndSetCurrentEvent(targetRef.current, event);
172 + });
173 + expect(clearedMarks).toContain(
174 + `--schedule-state-update-${formatLanes(
175 + ReactFiberLane.InputContinuousLane,
176 + )}-App`,
177 + );
178 + });
179 +});