DevTools Profiler: Add commit and post-commit durations to UI (#20984)
Brian Vaughn committed
Mar 17, 2021 at 12:27 UTC
bf11788bf0c2e861dc6378ac9ab59d37e7c3e812
14 files changed
+403
-43
packages/react-devtools-shared/src/__tests__/__snapshots__/profilingCache-test.js.snap
+94
@@ -26,6 +26,7 @@ Object {
26
},
27
},
28
"duration": 16,
29
+ "effectDuration": null,
30
"fiberActualDurations": Map {
31
1 => 16,
32
2 => 16,
@@ -39,6 +40,7 @@ Object {
40
5 => 1,
41
},
42
"interactionIDs": Array [],
43
+ "passiveEffectDuration": null,
44
"priorityLevel": "Normal",
45
"timestamp": 16,
46
}
@@ -63,6 +65,7 @@ Object {
65
},
66
},
67
"duration": 15,
68
+ "effectDuration": null,
69
"fiberActualDurations": Map {
70
1 => 15,
71
2 => 15,
@@ -76,6 +79,7 @@ Object {
79
4 => 2,
80
},
81
"interactionIDs": Array [],
82
+ "passiveEffectDuration": null,
83
"priorityLevel": "Normal",
84
"timestamp": 15,
85
}
@@ -93,6 +97,7 @@ Object {
97
},
98
},
99
"duration": 3,
100
+ "effectDuration": null,
101
"fiberActualDurations": Map {
102
5 => 3,
103
3 => 3,
@@ -102,6 +107,7 @@ Object {
107
3 => 0,
108
},
109
"interactionIDs": Array [],
110
+ "passiveEffectDuration": null,
111
"priorityLevel": "Immediate",
112
"timestamp": 18,
113
}
@@ -140,6 +146,7 @@ Object {
146
},
147
},
148
"duration": 12,
149
+ "effectDuration": null,
150
"fiberActualDurations": Map {
151
1 => 12,
152
2 => 12,
@@ -155,6 +162,7 @@ Object {
162
5 => 1,
163
},
164
"interactionIDs": Array [],
165
+ "passiveEffectDuration": null,
166
"priorityLevel": "Normal",
167
"timestamp": 12,
168
}
@@ -195,6 +203,7 @@ Object {
203
},
204
},
205
"duration": 13,
206
+ "effectDuration": null,
207
"fiberActualDurations": Map {
208
3 => 0,
209
4 => 1,
@@ -210,6 +219,7 @@ Object {
219
1 => 0,
220
},
221
"interactionIDs": Array [],
222
+ "passiveEffectDuration": null,
223
"priorityLevel": "Immediate",
224
"timestamp": 25,
225
}
@@ -236,6 +246,7 @@ Object {
246
},
247
},
248
"duration": 10,
249
+ "effectDuration": null,
250
"fiberActualDurations": Map {
251
3 => 0,
252
2 => 10,
@@ -247,6 +258,7 @@ Object {
258
1 => 0,
259
},
260
"interactionIDs": Array [],
261
+ "passiveEffectDuration": null,
262
"priorityLevel": "Immediate",
263
"timestamp": 35,
264
}
@@ -266,6 +278,7 @@ Object {
278
},
279
},
280
"duration": 10,
281
+ "effectDuration": null,
282
"fiberActualDurations": Map {
283
2 => 10,
284
1 => 10,
@@ -275,6 +288,7 @@ Object {
288
1 => 0,
289
},
290
"interactionIDs": Array [],
291
+ "passiveEffectDuration": null,
292
"priorityLevel": "Immediate",
293
"timestamp": 45,
294
}
@@ -329,6 +343,7 @@ Object {
343
],
344
],
345
"duration": 12,
346
+ "effectDuration": null,
347
"fiberActualDurations": Array [
348
Array [
349
1,
@@ -374,6 +389,7 @@ Object {
389
],
390
],
391
"interactionIDs": Array [],
392
+ "passiveEffectDuration": null,
393
"priorityLevel": "Normal",
394
"timestamp": 12,
395
},
@@ -423,6 +439,7 @@ Object {
439
],
440
],
441
"duration": 13,
442
+ "effectDuration": null,
443
"fiberActualDurations": Array [
444
Array [
445
3,
@@ -468,6 +485,7 @@ Object {
485
],
486
],
487
"interactionIDs": Array [],
488
+ "passiveEffectDuration": null,
489
"priorityLevel": "Immediate",
490
"timestamp": 25,
491
},
@@ -497,6 +515,7 @@ Object {
515
],
516
],
517
"duration": 10,
518
+ "effectDuration": null,
519
"fiberActualDurations": Array [
520
Array [
521
3,
@@ -526,6 +545,7 @@ Object {
545
],
546
],
547
"interactionIDs": Array [],
548
+ "passiveEffectDuration": null,
549
"priorityLevel": "Immediate",
550
"timestamp": 35,
551
},
@@ -545,6 +565,7 @@ Object {
565
],
566
],
567
"duration": 10,
568
+ "effectDuration": null,
569
"fiberActualDurations": Array [
570
Array [
571
2,
@@ -566,6 +587,7 @@ Object {
587
],
588
],
589
"interactionIDs": Array [],
590
+ "passiveEffectDuration": null,
591
"priorityLevel": "Immediate",
592
"timestamp": 45,
593
},
@@ -792,6 +814,7 @@ Object {
814
],
815
],
816
"duration": 11,
817
+ "effectDuration": null,
818
"fiberActualDurations": Array [
819
Array [
820
1,
@@ -829,6 +852,7 @@ Object {
852
],
853
],
854
"interactionIDs": Array [],
855
+ "passiveEffectDuration": null,
856
"priorityLevel": "Normal",
857
"timestamp": 11,
858
},
@@ -868,6 +892,7 @@ Object {
892
],
893
],
894
"duration": 11,
895
+ "effectDuration": null,
896
"fiberActualDurations": Array [
897
Array [
898
3,
@@ -905,6 +930,7 @@ Object {
930
],
931
],
932
"interactionIDs": Array [],
933
+ "passiveEffectDuration": null,
934
"priorityLevel": "Immediate",
935
"timestamp": 22,
936
},
@@ -954,6 +980,7 @@ Object {
980
],
981
],
982
"duration": 13,
983
+ "effectDuration": null,
984
"fiberActualDurations": Array [
985
Array [
986
3,
@@ -999,6 +1026,7 @@ Object {
1026
],
1027
],
1028
"interactionIDs": Array [],
1029
+ "passiveEffectDuration": null,
1030
"priorityLevel": "Immediate",
1031
"timestamp": 35,
1032
},
@@ -1183,6 +1211,7 @@ Object {
1211
},
1212
},
1213
"duration": 13,
1214
+ "effectDuration": null,
1215
"fiberActualDurations": Map {
1216
3 => 0,
1217
4 => 1,
@@ -1198,6 +1227,7 @@ Object {
1227
1 => 0,
1228
},
1229
"interactionIDs": Array [],
1230
+ "passiveEffectDuration": null,
1231
"priorityLevel": "Immediate",
1232
"timestamp": 13,
1233
},
@@ -1221,6 +1251,7 @@ Object {
1251
},
1252
},
1253
"duration": 10,
1254
+ "effectDuration": null,
1255
"fiberActualDurations": Map {
1256
3 => 0,
1257
2 => 10,
@@ -1232,6 +1263,7 @@ Object {
1263
1 => 0,
1264
},
1265
"interactionIDs": Array [],
1266
+ "passiveEffectDuration": null,
1267
"priorityLevel": "Immediate",
1268
"timestamp": 34,
1269
},
@@ -1248,6 +1280,7 @@ Object {
1280
},
1281
},
1282
"duration": 10,
1283
+ "effectDuration": null,
1284
"fiberActualDurations": Map {
1285
2 => 10,
1286
1 => 10,
@@ -1257,6 +1290,7 @@ Object {
1290
1 => 0,
1291
},
1292
"interactionIDs": Array [],
1293
+ "passiveEffectDuration": null,
1294
"priorityLevel": "Immediate",
1295
"timestamp": 44,
1296
},
@@ -1419,6 +1453,7 @@ Object {
1453
},
1454
},
1455
"duration": 11,
1456
+ "effectDuration": null,
1457
"fiberActualDurations": Map {
1458
11 => 11,
1459
12 => 11,
@@ -1432,6 +1467,7 @@ Object {
1467
14 => 1,
1468
},
1469
"interactionIDs": Array [],
1470
+ "passiveEffectDuration": null,
1471
"priorityLevel": "Normal",
1472
"timestamp": 24,
1473
},
@@ -1511,9 +1547,11 @@ Object {
1547
Object {
1548
"changeDescriptions": Map {},
1549
"duration": 0,
1550
+ "effectDuration": null,
1551
"fiberActualDurations": Map {},
1552
"fiberSelfDurations": Map {},
1553
"interactionIDs": Array [],
1554
+ "passiveEffectDuration": null,
1555
"priorityLevel": "Normal",
1556
"timestamp": 34,
1557
},
@@ -1636,6 +1674,7 @@ Object {
1674
],
1675
],
1676
"duration": 13,
1677
+ "effectDuration": null,
1678
"fiberActualDurations": Array [
1679
Array [
1680
3,
@@ -1681,6 +1720,7 @@ Object {
1720
],
1721
],
1722
"interactionIDs": Array [],
1723
+ "passiveEffectDuration": null,
1724
"priorityLevel": "Immediate",
1725
"timestamp": 13,
1726
},
@@ -1710,6 +1750,7 @@ Object {
1750
],
1751
],
1752
"duration": 10,
1753
+ "effectDuration": null,
1754
"fiberActualDurations": Array [
1755
Array [
1756
3,
@@ -1739,6 +1780,7 @@ Object {
1780
],
1781
],
1782
"interactionIDs": Array [],
1783
+ "passiveEffectDuration": null,
1784
"priorityLevel": "Immediate",
1785
"timestamp": 34,
1786
},
@@ -1758,6 +1800,7 @@ Object {
1800
],
1801
],
1802
"duration": 10,
1803
+ "effectDuration": null,
1804
"fiberActualDurations": Array [
1805
Array [
1806
2,
@@ -1779,6 +1822,7 @@ Object {
1822
],
1823
],
1824
"interactionIDs": Array [],
1825
+ "passiveEffectDuration": null,
1826
"priorityLevel": "Immediate",
1827
"timestamp": 44,
1828
},
@@ -1977,6 +2021,7 @@ Object {
2021
],
2022
],
2023
"duration": 11,
2024
+ "effectDuration": null,
2025
"fiberActualDurations": Array [
2026
Array [
2027
11,
@@ -2014,6 +2059,7 @@ Object {
2059
],
2060
],
2061
"interactionIDs": Array [],
2062
+ "passiveEffectDuration": null,
2063
"priorityLevel": "Normal",
2064
"timestamp": 24,
2065
},
@@ -2090,9 +2136,11 @@ Object {
2136
Object {
2137
"changeDescriptions": Array [],
2138
"duration": 0,
2139
+ "effectDuration": null,
2140
"fiberActualDurations": Array [],
2141
"fiberSelfDurations": Array [],
2142
"interactionIDs": Array [],
2143
+ "passiveEffectDuration": null,
2144
"priorityLevel": "Normal",
2145
"timestamp": 34,
2146
},
@@ -2197,6 +2245,7 @@ Object {
2245
Object {
2246
"changeDescriptions": Map {},
2247
"duration": 0,
2248
+ "effectDuration": null,
2249
"fiberActualDurations": Map {
2250
1 => 0,
2251
2 => 0,
@@ -2206,6 +2255,7 @@ Object {
2255
2 => 0,
2256
},
2257
"interactionIDs": Array [],
2258
+ "passiveEffectDuration": null,
2259
"priorityLevel": "Normal",
2260
"timestamp": 0,
2261
},
@@ -2262,6 +2312,7 @@ Object {
2312
},
2313
},
2314
"duration": 0,
2315
+ "effectDuration": null,
2316
"fiberActualDurations": Map {
2317
1 => 0,
2318
2 => 0,
@@ -2273,6 +2324,7 @@ Object {
2324
3 => 0,
2325
},
2326
"interactionIDs": Array [],
2327
+ "passiveEffectDuration": null,
2328
"priorityLevel": "Normal",
2329
"timestamp": 0,
2330
}
@@ -2292,6 +2344,7 @@ Object {
2344
},
2345
},
2346
"duration": 0,
2347
+ "effectDuration": null,
2348
"fiberActualDurations": Map {
2349
3 => 0,
2350
2 => 0,
@@ -2303,6 +2356,7 @@ Object {
2356
1 => 0,
2357
},
2358
"interactionIDs": Array [],
2359
+ "passiveEffectDuration": null,
2360
"priorityLevel": "Immediate",
2361
"timestamp": 0,
2362
}
@@ -2320,6 +2374,7 @@ Object {
2374
},
2375
},
2376
"duration": 0,
2377
+ "effectDuration": null,
2378
"fiberActualDurations": Map {
2379
3 => 0,
2380
},
@@ -2327,6 +2382,7 @@ Object {
2382
3 => 0,
2383
},
2384
"interactionIDs": Array [],
2385
+ "passiveEffectDuration": null,
2386
"priorityLevel": "Immediate",
2387
"timestamp": 0,
2388
}
@@ -2344,6 +2400,7 @@ Object {
2400
},
2401
},
2402
"duration": 0,
2403
+ "effectDuration": null,
2404
"fiberActualDurations": Map {
2405
3 => 0,
2406
},
@@ -2351,6 +2408,7 @@ Object {
2408
3 => 0,
2409
},
2410
"interactionIDs": Array [],
2411
+ "passiveEffectDuration": null,
2412
"priorityLevel": "Immediate",
2413
"timestamp": 0,
2414
}
@@ -2368,6 +2426,7 @@ Object {
2426
},
2427
},
2428
"duration": 0,
2429
+ "effectDuration": null,
2430
"fiberActualDurations": Map {
2431
3 => 0,
2432
2 => 0,
@@ -2379,6 +2438,7 @@ Object {
2438
1 => 0,
2439
},
2440
"interactionIDs": Array [],
2441
+ "passiveEffectDuration": null,
2442
"priorityLevel": "Immediate",
2443
"timestamp": 0,
2444
}
@@ -2403,6 +2463,7 @@ Object {
2463
],
2464
],
2465
"duration": 0,
2466
+ "effectDuration": null,
2467
"fiberActualDurations": Array [
2468
Array [
2469
1,
@@ -2432,6 +2493,7 @@ Object {
2493
],
2494
],
2495
"interactionIDs": Array [],
2496
+ "passiveEffectDuration": null,
2497
"priorityLevel": "Normal",
2498
"timestamp": 0,
2499
},
@@ -2451,6 +2513,7 @@ Object {
2513
],
2514
],
2515
"duration": 0,
2516
+ "effectDuration": null,
2517
"fiberActualDurations": Array [
2518
Array [
2519
3,
@@ -2480,6 +2543,7 @@ Object {
2543
],
2544
],
2545
"interactionIDs": Array [],
2546
+ "passiveEffectDuration": null,
2547
"priorityLevel": "Immediate",
2548
"timestamp": 0,
2549
},
@@ -2497,6 +2561,7 @@ Object {
2561
],
2562
],
2563
"duration": 0,
2564
+ "effectDuration": null,
2565
"fiberActualDurations": Array [
2566
Array [
2567
3,
@@ -2510,6 +2575,7 @@ Object {
2575
],
2576
],
2577
"interactionIDs": Array [],
2578
+ "passiveEffectDuration": null,
2579
"priorityLevel": "Immediate",
2580
"timestamp": 0,
2581
},
@@ -2527,6 +2593,7 @@ Object {
2593
],
2594
],
2595
"duration": 0,
2596
+ "effectDuration": null,
2597
"fiberActualDurations": Array [
2598
Array [
2599
3,
@@ -2540,6 +2607,7 @@ Object {
2607
],
2608
],
2609
"interactionIDs": Array [],
2610
+ "passiveEffectDuration": null,
2611
"priorityLevel": "Immediate",
2612
"timestamp": 0,
2613
},
@@ -2557,6 +2625,7 @@ Object {
2625
],
2626
],
2627
"duration": 0,
2628
+ "effectDuration": null,
2629
"fiberActualDurations": Array [
2630
Array [
2631
3,
@@ -2586,6 +2655,7 @@ Object {
2655
],
2656
],
2657
"interactionIDs": Array [],
2658
+ "passiveEffectDuration": null,
2659
"priorityLevel": "Immediate",
2660
"timestamp": 0,
2661
},
@@ -2721,6 +2791,7 @@ Object {
2791
},
2792
},
2793
"duration": 0,
2794
+ "effectDuration": null,
2795
"fiberActualDurations": Map {
2796
1 => 0,
2797
2 => 0,
@@ -2740,6 +2811,7 @@ Object {
2811
7 => 0,
2812
},
2813
"interactionIDs": Array [],
2814
+ "passiveEffectDuration": null,
2815
"priorityLevel": "Normal",
2816
"timestamp": 0,
2817
}
@@ -2793,6 +2865,7 @@ Object {
2865
},
2866
},
2867
"duration": 0,
2868
+ "effectDuration": null,
2869
"fiberActualDurations": Map {
2870
5 => 0,
2871
4 => 0,
@@ -2810,6 +2883,7 @@ Object {
2883
2 => 0,
2884
},
2885
"interactionIDs": Array [],
2886
+ "passiveEffectDuration": null,
2887
"priorityLevel": "Immediate",
2888
"timestamp": 0,
2889
}
@@ -2857,6 +2931,7 @@ Object {
2931
},
2932
},
2933
"duration": 0,
2934
+ "effectDuration": null,
2935
"fiberActualDurations": Map {
2936
5 => 0,
2937
4 => 0,
@@ -2876,6 +2951,7 @@ Object {
2951
1 => 0,
2952
},
2953
"interactionIDs": Array [],
2954
+ "passiveEffectDuration": null,
2955
"priorityLevel": "Immediate",
2956
"timestamp": 0,
2957
}
@@ -2924,6 +3000,7 @@ Object {
3000
},
3001
},
3002
"duration": 0,
3003
+ "effectDuration": null,
3004
"fiberActualDurations": Map {
3005
5 => 0,
3006
4 => 0,
@@ -2943,6 +3020,7 @@ Object {
3020
1 => 0,
3021
},
3022
"interactionIDs": Array [],
3023
+ "passiveEffectDuration": null,
3024
"priorityLevel": "Immediate",
3025
"timestamp": 0,
3026
}
@@ -2990,6 +3068,7 @@ Object {
3068
},
3069
},
3070
"duration": 0,
3071
+ "effectDuration": null,
3072
"fiberActualDurations": Map {
3073
5 => 0,
3074
4 => 0,
@@ -3009,6 +3088,7 @@ Object {
3088
1 => 0,
3089
},
3090
"interactionIDs": Array [],
3091
+ "passiveEffectDuration": null,
3092
"priorityLevel": "Immediate",
3093
"timestamp": 0,
3094
}
@@ -3073,6 +3153,7 @@ Object {
3153
],
3154
],
3155
"duration": 0,
3156
+ "effectDuration": null,
3157
"fiberActualDurations": Array [
3158
Array [
3159
1,
@@ -3134,6 +3215,7 @@ Object {
3215
],
3216
],
3217
"interactionIDs": Array [],
3218
+ "passiveEffectDuration": null,
3219
"priorityLevel": "Normal",
3220
"timestamp": 0,
3221
},
@@ -3199,6 +3281,7 @@ Object {
3281
],
3282
],
3283
"duration": 0,
3284
+ "effectDuration": null,
3285
"fiberActualDurations": Array [
3286
Array [
3287
5,
@@ -3252,6 +3335,7 @@ Object {
3335
],
3336
],
3337
"interactionIDs": Array [],
3338
+ "passiveEffectDuration": null,
3339
"priorityLevel": "Immediate",
3340
"timestamp": 0,
3341
},
@@ -3311,6 +3395,7 @@ Object {
3395
],
3396
],
3397
"duration": 0,
3398
+ "effectDuration": null,
3399
"fiberActualDurations": Array [
3400
Array [
3401
5,
@@ -3372,6 +3457,7 @@ Object {
3457
],
3458
],
3459
"interactionIDs": Array [],
3460
+ "passiveEffectDuration": null,
3461
"priorityLevel": "Immediate",
3462
"timestamp": 0,
3463
},
@@ -3432,6 +3518,7 @@ Object {
3518
],
3519
],
3520
"duration": 0,
3521
+ "effectDuration": null,
3522
"fiberActualDurations": Array [
3523
Array [
3524
5,
@@ -3493,6 +3580,7 @@ Object {
3580
],
3581
],
3582
"interactionIDs": Array [],
3583
+ "passiveEffectDuration": null,
3584
"priorityLevel": "Immediate",
3585
"timestamp": 0,
3586
},
@@ -3552,6 +3640,7 @@ Object {
3640
],
3641
],
3642
"duration": 0,
3643
+ "effectDuration": null,
3644
"fiberActualDurations": Array [
3645
Array [
3646
5,
@@ -3613,6 +3702,7 @@ Object {
3702
],
3703
],
3704
"interactionIDs": Array [],
3705
+ "passiveEffectDuration": null,
3706
"priorityLevel": "Immediate",
3707
"timestamp": 0,
3708
},
@@ -3887,6 +3977,7 @@ Object {
3977
],
3978
],
3979
"duration": 11,
3980
+ "effectDuration": null,
3981
"fiberActualDurations": Array [
3982
Array [
3983
1,
@@ -3926,6 +4017,7 @@ Object {
4017
"interactionIDs": Array [
4018
0,
4019
],
4020
+ "passiveEffectDuration": null,
4021
"priorityLevel": "Normal",
4022
"timestamp": 11,
4023
},
@@ -3965,6 +4057,7 @@ Object {
4057
],
4058
],
4059
"duration": 11,
4060
+ "effectDuration": null,
4061
"fiberActualDurations": Array [
4062
Array [
4063
3,
@@ -4004,6 +4097,7 @@ Object {
4097
"interactionIDs": Array [
4098
1,
4099
],
4100
+ "passiveEffectDuration": null,
4101
"priorityLevel": "Immediate",
4102
"timestamp": 22,
4103
},
packages/react-devtools-shared/src/backend/renderer.js
+46
@@ -2097,6 +2097,25 @@ export function attach(
2097
// Checking root.memoizedInteractions handles multi-renderer edge-case-
2098
// where some v16 renderers support profiling and others don't.
2099
if (isProfiling && root.memoizedInteractions != null) {
2100
+ // Profiling durations are only available for certain builds.
2101
+ // If available, they'll be stored on the HostRoot.
2102
+ let effectDuration = null;
2103
+ let passiveEffectDuration = null;
2104
+ const hostRoot = root.current;
2105
+ if (hostRoot != null) {
2106
+ const stateNode = hostRoot.stateNode;
2107
+ if (stateNode != null) {
2108
+ effectDuration =
2109
+ stateNode.effectDuration != null
2110
+ ? stateNode.effectDuration
2111
+ : null;
2112
+ passiveEffectDuration =
2113
+ stateNode.passiveEffectDuration != null
2114
+ ? stateNode.passiveEffectDuration
2115
+ : null;
2116
+ }
2117
+ }
2118
+
2119
// If profiling is active, store commit time and duration, and the current interactions.
2120
// The frontend may request this information after profiling has stopped.
2121
currentCommitProfilingMetadata = {
@@ -2111,6 +2130,8 @@ export function attach(
2130
),
2131
maxActualDuration: 0,
2132
priorityLevel: null,
2133
+ effectDuration,
2134
+ passiveEffectDuration,
2135
};
2136
}
2137
@@ -2149,6 +2170,23 @@ export function attach(
2170
const isProfilingSupported = root.memoizedInteractions != null;
2171
2172
if (isProfiling && isProfilingSupported) {
2173
+ // Profiling durations are only available for certain builds.
2174
+ // If available, they'll be stored on the HostRoot.
2175
+ let effectDuration = null;
2176
+ let passiveEffectDuration = null;
2177
+ const hostRoot = root.current;
2178
+ if (hostRoot != null) {
2179
+ const stateNode = hostRoot.stateNode;
2180
+ if (stateNode != null) {
2181
+ effectDuration =
2182
+ stateNode.effectDuration != null ? stateNode.effectDuration : null;
2183
+ passiveEffectDuration =
2184
+ stateNode.passiveEffectDuration != null
2185
+ ? stateNode.passiveEffectDuration
2186
+ : null;
2187
+ }
2188
+ }
2189
+
2190
// If profiling is active, store commit time and duration, and the current interactions.
2191
// The frontend may request this information after profiling has stopped.
2192
currentCommitProfilingMetadata = {
@@ -2164,6 +2202,8 @@ export function attach(
2202
maxActualDuration: 0,
2203
priorityLevel:
2204
priorityLevel == null ? null : formatPriorityLevel(priorityLevel),
2205
+ effectDuration,
2206
+ passiveEffectDuration,
2207
};
2208
}
2209
@@ -3294,8 +3334,10 @@ export function attach(
3334
changeDescriptions: Map<number, ChangeDescription> | null,
3335
commitTime: number,
3336
durations: Array<number>,
3337
+ effectDuration: number | null,
3338
interactions: Array<Interaction>,
3339
maxActualDuration: number,
3340
+ passiveEffectDuration: number | null,
3341
priorityLevel: string | null,
3342
|};
3343
@@ -3349,8 +3391,10 @@ export function attach(
3391
const {
3392
changeDescriptions,
3393
durations,
3394
+ effectDuration,
3395
interactions,
3396
maxActualDuration,
3397
+ passiveEffectDuration,
3398
priorityLevel,
3399
commitTime,
3400
} = commitProfilingData;
@@ -3386,9 +3430,11 @@ export function attach(
3430
? Array.from(changeDescriptions.entries())
3431
: null,
3432
duration: maxActualDuration,
3433
+ effectDuration,
3434
fiberActualDurations,
3435
fiberSelfDurations,
3436
interactionIDs,
3437
+ passiveEffectDuration,
3438
priorityLevel,
3439
timestamp: commitTime,
3440
});
packages/react-devtools-shared/src/backend/types.js
+4
@@ -156,11 +156,15 @@ export type CommitDataBackend = {|
156
// Tuple of fiber ID and change description
157
changeDescriptions: Array<[number, ChangeDescription]> | null,
158
duration: number,
159
+ // Only available in certain (newer) React builds,
160
+ effectDuration: number | null,
161
// Tuple of fiber ID and actual duration
162
fiberActualDurations: Array<[number, number]>,
163
// Tuple of fiber ID and computed "self" duration
164
fiberSelfDurations: Array<[number, number]>,
165
interactionIDs: Array<number>,
166
+ // Only available in certain (newer) React builds,
167
+ passiveEffectDuration: number | null,
168
priorityLevel: string | null,
169
timestamp: number,
170
|};
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarCommitInfo.css
+16
@@ -63,3 +63,19 @@
63
height: 100%;
64
color: var(--color-dim);
65
}
66
+
67
+.DurationsList {
68
+ list-style: none;
69
+ margin: 0.25rem 0 0 0;
70
+ padding: 0;
71
+ background: var(--color-background-inactive);
72
+ padding: 0.25rem 0.5rem;
73
+ border-radius: 0.25rem;
74
+}
75
+
76
+.DurationsListItem {
77
+ margin: 0.25rem 0 0 0;
78
+}
79
+.DurationsListItem:first-of-type {
80
+ margin: 0;
81
+}
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarCommitInfo.js
+43
-4
@@ -34,7 +34,9 @@ export default function SidebarCommitInfo(_: Props) {
34
const {interactions} = profilerStore.getDataForRoot(rootID);
35
const {
36
duration,
37
+ effectDuration,
38
interactionIDs,
39
+ passiveEffectDuration,
40
priorityLevel,
41
timestamp,
42
} = profilerStore.getCommitData(rootID, selectedCommitIndex);
@@ -44,6 +46,9 @@ export default function SidebarCommitInfo(_: Props) {
46
selectInteraction(interactionID);
47
};
48
49
+ const hasCommitPhaseDurations =
50
+ effectDuration !== null || passiveEffectDuration !== null;
51
+
52
return (
53
<Fragment>
54
<div className={styles.Toolbar}>Commit information</div>
@@ -59,10 +64,44 @@ export default function SidebarCommitInfo(_: Props) {
64
<label className={styles.Label}>Committed at</label>:{' '}
65
<span className={styles.Value}>{formatTime(timestamp)}s</span>
66
</li>
62
- <li className={styles.ListItem}>
63
- <label className={styles.Label}>Render duration</label>:{' '}
64
- <span className={styles.Value}>{formatDuration(duration)}ms</span>
65
- </li>
67
+
68
+ {!hasCommitPhaseDurations && (
69
+ <li className={styles.ListItem}>
70
+ <label className={styles.Label}>Render duration</label>:{' '}
71
+ <span className={styles.Value}>{formatDuration(duration)}ms</span>
72
+ </li>
73
+ )}
74
+
75
+ {hasCommitPhaseDurations && (
76
+ <li className={styles.ListItem}>
77
+ <label className={styles.Label}>Durations</label>
78
+ <ul className={styles.DurationsList}>
79
+ <li className={styles.DurationsListItem}>
80
+ <label className={styles.Label}>Render</label>:{' '}
81
+ <span className={styles.Value}>
82
+ {formatDuration(duration)}ms
83
+ </span>
84
+ </li>
85
+ {effectDuration !== null && (
86
+ <li className={styles.DurationsListItem}>
87
+ <label className={styles.Label}>Layout effects</label>:{' '}
88
+ <span className={styles.Value}>
89
+ {formatDuration(effectDuration)}ms
90
+ </span>
91
+ </li>
92
+ )}
93
+ {passiveEffectDuration !== null && (
94
+ <li className={styles.DurationsListItem}>
95
+ <label className={styles.Label}>Passive effects</label>:{' '}
96
+ <span className={styles.Value}>
97
+ {formatDuration(passiveEffectDuration)}ms
98
+ </span>
99
+ </li>
100
+ )}
101
+ </ul>
102
+ </li>
103
+ )}
104
+
105
<li className={styles.Interactions}>
106
<label className={styles.Label}>Interactions</label>:
107
<div className={styles.InteractionList}>
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.css
+53
@@ -7,3 +7,56 @@
7
*/
8
overflow-x: hidden !important;
9
}
10
+
11
+.Tooltip {
12
+ margin-top: 2.5rem;
13
+}
14
+
15
+.TooltipList {
16
+ list-style: none;
17
+ padding: 0;
18
+ margin: 0;
19
+}
20
+
21
+.TooltipListItem {
22
+ display: flex;
23
+}
24
+
25
+.TooltipLabel {
26
+ font-weight: bold;
27
+ margin-right: 0.25rem;
28
+}
29
+.TooltipLabel:after {
30
+ content: ':';
31
+}
32
+
33
+.TooltipValue {
34
+ flex-grow: 1;
35
+ text-align: end;
36
+}
37
+
38
+.DurationsWrapper {
39
+ flex-grow: 1;
40
+}
41
+
42
+.DurationsList {
43
+ list-style: none;
44
+ margin: 0 0 0 1rem;
45
+ padding: 0;
46
+}
47
+
48
+.DurationsListItem {
49
+ display: flex;
50
+}
51
+
52
+.DurationsLabel {
53
+ margin-right: 0.25rem;
54
+}
55
+.DurationsLabel:after {
56
+ content: ':';
57
+}
58
+
59
+.DurationsValue {
60
+ flex-grow: 1;
61
+ text-align: end;
62
+}
\ No newline at end of file
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js
+83
-16
@@ -7,6 +7,8 @@
7
* @flow
8
*/
9
10
+import type {CommitDataFrontend} from './types';
11
+
12
import * as React from 'react';
13
import {useEffect, useMemo, useRef, useState} from 'react';
14
import AutoSizer from 'react-virtualized-auto-sizer';
@@ -19,7 +21,6 @@ import Tooltip from './Tooltip';
21
import styles from './SnapshotCommitList.css';
22
23
export type ItemData = {|
22
- commitDurations: Array<number>,
24
commitTimes: Array<number>,
25
filteredCommitIndices: Array<number>,
26
maxDuration: number,
@@ -28,36 +29,40 @@ export type ItemData = {|
29
selectCommitIndex: (index: number) => void,
30
setHoveredCommitIndex: (index: number) => void,
31
startCommitDrag: (newDragState: DragState) => void,
32
+ totalDurations: Array<number>,
33
|};
34
35
type Props = {|
34
- commitDurations: Array<number>,
36
+ commitData: CommitDataFrontend,
37
commitTimes: Array<number>,
38
filteredCommitIndices: Array<number>,
39
selectedCommitIndex: number | null,
40
selectedFilteredCommitIndex: number | null,
41
selectCommitIndex: (index: number) => void,
42
+ totalDurations: Array<number>,
43
|};
44
45
export default function SnapshotCommitList({
43
- commitDurations,
46
+ commitData,
47
commitTimes,
48
filteredCommitIndices,
49
selectedCommitIndex,
50
selectedFilteredCommitIndex,
51
selectCommitIndex,
52
+ totalDurations,
53
}: Props) {
54
return (
55
<AutoSizer>
56
{({height, width}) => (
57
<List
54
- commitDurations={commitDurations}
58
+ commitData={commitData}
59
commitTimes={commitTimes}
60
height={height}
61
filteredCommitIndices={filteredCommitIndices}
62
selectedCommitIndex={selectedCommitIndex}
63
selectedFilteredCommitIndex={selectedFilteredCommitIndex}
64
selectCommitIndex={selectCommitIndex}
65
+ totalDurations={totalDurations}
66
width={width}
67
/>
68
)}
@@ -66,13 +71,14 @@ export default function SnapshotCommitList({
71
}
72
73
type ListProps = {|
69
- commitDurations: Array<number>,
74
+ commitData: CommitDataFrontend,
75
commitTimes: Array<number>,
76
height: number,
77
filteredCommitIndices: Array<number>,
78
selectedCommitIndex: number | null,
79
selectedFilteredCommitIndex: number | null,
80
selectCommitIndex: (index: number) => void,
81
+ totalDurations: Array<number>,
82
width: number,
83
|};
84
@@ -83,13 +89,14 @@ type DragState = {
89
};
90
91
function List({
86
- commitDurations,
92
+ commitData,
93
selectedCommitIndex,
94
commitTimes,
95
height,
96
filteredCommitIndices,
97
selectedFilteredCommitIndex,
98
selectCommitIndex,
99
+ totalDurations,
100
width,
101
}: ListProps) {
102
const listRef = useRef<FixedSizeList<ItemData> | null>(null);
@@ -111,8 +118,8 @@ function List({
118
[filteredCommitIndices, width],
119
);
120
const maxDuration = useMemo(
114
- () => commitDurations.reduce((max, duration) => Math.max(max, duration), 0),
115
- [commitDurations],
121
+ () => totalDurations.reduce((max, duration) => Math.max(max, duration), 0),
122
+ [totalDurations],
123
);
124
125
const maxCommitIndex = filteredCommitIndices.length - 1;
@@ -176,7 +183,6 @@ function List({
183
// Pass required contextual data down to the ListItem renderer.
184
const itemData = useMemo<ItemData>(
185
() => ({
179
- commitDurations,
186
commitTimes,
187
filteredCommitIndices,
188
maxDuration,
@@ -185,9 +191,9 @@ function List({
191
selectCommitIndex,
192
setHoveredCommitIndex,
193
startCommitDrag: setDragState,
194
+ totalDurations,
195
}),
196
[
190
- commitDurations,
197
commitTimes,
198
filteredCommitIndices,
199
maxDuration,
@@ -195,20 +201,81 @@ function List({
201
selectedFilteredCommitIndex,
202
selectCommitIndex,
203
setHoveredCommitIndex,
204
+ totalDurations,
205
],
206
);
207
208
let tooltipLabel = null;
209
if (hoveredCommitIndex !== null) {
203
- const commitDuration = commitDurations[hoveredCommitIndex];
204
- const commitTime = commitTimes[hoveredCommitIndex];
205
- tooltipLabel = `${formatDuration(commitDuration)}ms at ${formatTime(
206
- commitTime,
207
- )}s`;
210
+ const {
211
+ duration,
212
+ effectDuration,
213
+ passiveEffectDuration,
214
+ priorityLevel,
215
+ timestamp,
216
+ } = commitData[hoveredCommitIndex];
217
+
218
+ // Only some React versions include commit durations.
219
+ // Show a richer tooltip only for builds that have that info.
220
+ if (effectDuration !== null || passiveEffectDuration !== null) {
221
+ tooltipLabel = (
222
+ <ul className={styles.TooltipList}>
223
+ {priorityLevel !== null && (
224
+ <li className={styles.TooltipListItem}>
225
+ <label className={styles.TooltipLabel}>Priority</label>
226
+ <span className={styles.TooltipValue}>{priorityLevel}</span>
227
+ </li>
228
+ )}
229
+ <li className={styles.TooltipListItem}>
230
+ <label className={styles.TooltipLabel}>Committed at</label>
231
+ <span className={styles.TooltipValue}>
232
+ {formatTime(timestamp)}s
233
+ </span>
234
+ </li>
235
+ <li className={styles.TooltipListItem}>
236
+ <div className={styles.DurationsWrapper}>
237
+ <label className={styles.TooltipLabel}>Durations</label>
238
+ <ul className={styles.DurationsList}>
239
+ <li className={styles.DurationsListItem}>
240
+ <label className={styles.DurationsLabel}>Render</label>
241
+ <span className={styles.DurationsValue}>
242
+ {formatDuration(duration)}ms
243
+ </span>
244
+ </li>
245
+ {effectDuration !== null && (
246
+ <li className={styles.DurationsListItem}>
247
+ <label className={styles.DurationsLabel}>
248
+ Layout effects
249
+ </label>
250
+ <span className={styles.DurationsValue}>
251
+ {formatDuration(effectDuration)}ms
252
+ </span>
253
+ </li>
254
+ )}
255
+ {passiveEffectDuration !== null && (
256
+ <li className={styles.DurationsListItem}>
257
+ <label className={styles.DurationsLabel}>
258
+ Passive effects
259
+ </label>
260
+ <span className={styles.DurationsValue}>
261
+ {formatDuration(passiveEffectDuration)}ms
262
+ </span>
263
+ </li>
264
+ )}
265
+ </ul>
266
+ </div>
267
+ </li>
268
+ </ul>
269
+ );
270
+ } else {
271
+ tooltipLabel = `${formatDuration(duration)}ms at ${formatTime(
272
+ timestamp,
273
+ )}s`;
274
+ }
275
}
276
277
return (
211
- <Tooltip label={tooltipLabel}>
278
+ <Tooltip className={styles.Tooltip} label={tooltipLabel}>
279
<div
280
ref={divRef}
281
style={{height, width}}
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.css
+6
-1
@@ -11,9 +11,14 @@
11
background-color: var(--color-background);
12
}
13
14
-.Inner {
14
+.Inner,
15
+.InnerSelected {
16
width: 100%;
17
min-height: 2px;
18
background-color: var(--color-commit-did-not-render-fill);
19
color: var(--color-commit-did-not-render-fill-text);
20
}
21
+
22
+.InnerSelected {
23
+ background-color: var(--color-button-active);
24
+}
\ No newline at end of file
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js
+13
-15
@@ -10,7 +10,7 @@
10
import * as React from 'react';
11
import {memo} from 'react';
12
import {areEqual} from 'react-window';
13
-import {getGradientColor, formatDuration, formatTime} from './utils';
13
+import {getGradientColor} from './utils';
14
15
import styles from './SnapshotCommitListItem.css';
16
@@ -25,20 +25,18 @@ type Props = {
25
26
function SnapshotCommitListItem({data: itemData, index, style}: Props) {
27
const {
28
- commitDurations,
29
- commitTimes,
28
filteredCommitIndices,
29
maxDuration,
30
selectedCommitIndex,
31
selectCommitIndex,
32
setHoveredCommitIndex,
33
startCommitDrag,
34
+ totalDurations,
35
} = itemData;
36
37
index = filteredCommitIndices[index];
38
40
- const commitDuration = commitDurations[index];
41
- const commitTime = commitTimes[index];
39
+ const totalDuration = totalDurations[index];
40
41
// Use natural cbrt for bar height.
42
// This prevents one (or a few) outliers from squishing the majority of other commits.
@@ -46,14 +44,13 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
44
const heightScale =
45
Math.min(
46
1,
49
- Math.max(0, Math.cbrt(commitDuration) / Math.cbrt(maxDuration)),
47
+ Math.max(0, Math.cbrt(totalDuration) / Math.cbrt(maxDuration)),
48
) || 0;
49
50
// Use a linear scale for color.
51
// This gives some visual contrast between cheaper and more expensive commits
52
// and somewhat compensates for the cbrt scale height.
55
- const colorScale =
56
- Math.min(1, Math.max(0, commitDuration / maxDuration)) || 0;
53
+ const colorScale = Math.min(1, Math.max(0, totalDuration / maxDuration)) || 0;
54
55
const isSelected = selectedCommitIndex === index;
56
@@ -71,6 +68,11 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
68
}
69
};
70
71
+ let backgroundColor;
72
+ if (!isSelected && totalDuration > 0) {
73
+ backgroundColor = getGradientColor(colorScale);
74
+ }
75
+
76
return (
77
<div
78
className={styles.Outer}
@@ -82,16 +84,12 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
84
borderBottom: isSelected
85
? '3px solid var(--color-tab-selected-border)'
86
: undefined,
85
- }}
86
- title={`Duration ${formatDuration(commitDuration)}ms at ${formatTime(
87
- commitTime,
88
- )}s`}>
87
+ }}>
88
<div
90
- className={styles.Inner}
89
+ className={isSelected ? styles.InnerSelected : styles.Inner}
90
style={{
91
height: `${Math.round(heightScale * 100)}%`,
93
- backgroundColor:
94
- commitDuration > 0 ? getGradientColor(colorScale) : undefined,
92
+ backgroundColor,
93
}}
94
/>
95
</div>
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotSelector.js
+8
-3
@@ -32,10 +32,14 @@ export default function SnapshotSelector(_: Props) {
32
const {profilerStore} = useContext(StoreContext);
33
const {commitData} = profilerStore.getDataForRoot(((rootID: any): number));
34
35
- const commitDurations: Array<number> = [];
35
+ const totalDurations: Array<number> = [];
36
const commitTimes: Array<number> = [];
37
commitData.forEach(commitDatum => {
38
- commitDurations.push(commitDatum.duration);
38
+ totalDurations.push(
39
+ commitDatum.duration +
40
+ (commitDatum.effectDuration || 0) +
41
+ (commitDatum.passiveEffectDuration || 0),
42
+ );
43
commitTimes.push(commitDatum.timestamp);
44
});
45
@@ -151,12 +155,13 @@ export default function SnapshotSelector(_: Props) {
155
tabIndex={0}>
156
{numFilteredCommits > 0 && (
157
<SnapshotCommitList
154
- commitDurations={commitDurations}
158
+ commitData={commitData}
159
commitTimes={commitTimes}
160
filteredCommitIndices={filteredCommitIndices}
161
selectedCommitIndex={selectedCommitIndex}
162
selectedFilteredCommitIndex={selectedFilteredCommitIndex}
163
selectCommitIndex={selectCommitIndex}
164
+ totalDurations={totalDurations}
165
/>
166
)}
167
{numFilteredCommits === 0 && (
packages/react-devtools-shared/src/devtools/views/Profiler/Tooltip.js
+5
-2
@@ -7,7 +7,7 @@ import styles from './Tooltip.css';
7
8
const initialTooltipState = {height: 0, mouseX: 0, mouseY: 0, width: 0};
9
10
-export default function Tooltip({children, label}: any) {
10
+export default function Tooltip({children, className, label, style}: any) {
11
const containerRef = useRef(null);
12
const tooltipRef = useRef(null);
13
@@ -36,7 +36,10 @@ export default function Tooltip({children, label}: any) {
36
className={styles.Container}
37
onMouseMove={onMouseMove}
38
ref={containerRef}>
39
- <div ref={tooltipRef} className={`${styles.Tooltip} ${tooltipClassName}`}>
39
+ <div
40
+ className={`${styles.Tooltip} ${tooltipClassName} ${className || ''}`}
41
+ ref={tooltipRef}
42
+ style={style}>
43
{label}
44
</div>
45
{children}
packages/react-devtools-shared/src/devtools/views/Profiler/types.js
+11
-1
@@ -52,9 +52,13 @@ export type CommitDataFrontend = {|
52
// Map of Fiber (ID) to a description of what changed in this commit.
53
changeDescriptions: Map<number, ChangeDescription> | null,
54
55
- // How long was this commit?
55
+ // How long was the render phase?
56
duration: number,
57
58
+ // How long was the layout commit phase?
59
+ // Note that not all builds of React expose this property.
60
+ effectDuration: number | null,
61
+
62
// Map of Fiber (ID) to actual duration for this commit;
63
// Fibers that did not render will not have entries in this Map.
64
fiberActualDurations: Map<number, number>,
@@ -66,6 +70,10 @@ export type CommitDataFrontend = {|
70
// Which interactions (IDs) were associated with this commit.
71
interactionIDs: Array<number>,
72
73
+ // How long was the passive commit phase?
74
+ // Note that not all builds of React expose this property.
75
+ passiveEffectDuration: number | null,
76
+
77
// Priority level of the commit (if React provided this info)
78
priorityLevel: string | null,
79
@@ -113,11 +121,13 @@ export type ProfilingDataFrontend = {|
121
export type CommitDataExport = {|
122
changeDescriptions: Array<[number, ChangeDescription]> | null,
123
duration: number,
124
+ effectDuration: number | null,
125
// Tuple of fiber ID and actual duration
126
fiberActualDurations: Array<[number, number]>,
127
// Tuple of fiber ID and computed "self" duration
128
fiberSelfDurations: Array<[number, number]>,
129
interactionIDs: Array<number>,
130
+ passiveEffectDuration: number | null,
131
priorityLevel: string | null,
132
timestamp: number,
133
|};
packages/react-devtools-shared/src/devtools/views/Profiler/utils.js
+10
@@ -75,11 +75,13 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
75
? new Map(commitDataBackend.changeDescriptions)
76
: null,
77
duration: commitDataBackend.duration,
78
+ effectDuration: commitDataBackend.effectDuration,
79
fiberActualDurations: new Map(
80
commitDataBackend.fiberActualDurations,
81
),
82
fiberSelfDurations: new Map(commitDataBackend.fiberSelfDurations),
83
interactionIDs: commitDataBackend.interactionIDs,
84
+ passiveEffectDuration: commitDataBackend.passiveEffectDuration,
85
priorityLevel: commitDataBackend.priorityLevel,
86
timestamp: commitDataBackend.timestamp,
87
}),
@@ -129,18 +131,22 @@ export function prepareProfilingDataFrontendFromExport(
131
({
132
changeDescriptions,
133
duration,
134
+ effectDuration,
135
fiberActualDurations,
136
fiberSelfDurations,
137
interactionIDs,
138
+ passiveEffectDuration,
139
priorityLevel,
140
timestamp,
141
}) => ({
142
changeDescriptions:
143
changeDescriptions != null ? new Map(changeDescriptions) : null,
144
duration,
145
+ effectDuration,
146
fiberActualDurations: new Map(fiberActualDurations),
147
fiberSelfDurations: new Map(fiberSelfDurations),
148
interactionIDs,
149
+ passiveEffectDuration,
150
priorityLevel,
151
timestamp,
152
}),
@@ -180,9 +186,11 @@ export function prepareProfilingDataExport(
186
({
187
changeDescriptions,
188
duration,
189
+ effectDuration,
190
fiberActualDurations,
191
fiberSelfDurations,
192
interactionIDs,
193
+ passiveEffectDuration,
194
priorityLevel,
195
timestamp,
196
}) => ({
@@ -191,9 +199,11 @@ export function prepareProfilingDataExport(
199
? Array.from(changeDescriptions.entries())
200
: null,
201
duration,
202
+ effectDuration,
203
fiberActualDurations: Array.from(fiberActualDurations.entries()),
204
fiberSelfDurations: Array.from(fiberSelfDurations.entries()),
205
interactionIDs,
206
+ passiveEffectDuration,
207
priorityLevel,
208
timestamp,
209
}),
packages/react-devtools-shell/src/app/InteractionTracing/index.js
+11
-1
@@ -8,7 +8,13 @@
8
*/
9
10
import * as React from 'react';
11
-import {Fragment, useCallback, useEffect, useState} from 'react';
11
+import {
12
+ Fragment,
13
+ useCallback,
14
+ useLayoutEffect,
15
+ useEffect,
16
+ useState,
17
+} from 'react';
18
import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';
19
import {
20
unstable_trace as trace,
@@ -68,6 +74,10 @@ export default function InteractionTracing() {
74
}
75
}, [count, shouldCascade]);
76
77
+ useLayoutEffect(() => {
78
+ Math.sqrt(100 * 100 * 100 * 100 * 100);
79
+ });
80
+
81
return (
82
<Fragment>
83
<h1>Interaction Tracing</h1>