@samitouri / QOS-React / commits / bdc23c3dba

DevTools shows which fibers scheduled the current update (#21171)

Brian Vaughn committed Apr 9, 2021 at 10:35 UTC bdc23c3dba86eaa03c7accecc16e8fd997e9185e
17 files changed +639 -56
packages/react-devtools-shared/src/__tests__/__snapshots__/ownersListContext-test.js.snap
+12
@@ -13,18 +13,21 @@ Array [
13 "displayName": "Grandparent",
14 "hocDisplayNames": null,
15 "id": 2,
16 + "key": null,
17 "type": 5,
18 },
19 Object {
20 "displayName": "Parent",
21 "hocDisplayNames": null,
22 "id": 3,
23 + "key": null,
24 "type": 5,
25 },
26 Object {
27 "displayName": "Child",
28 "hocDisplayNames": null,
29 "id": 4,
30 + "key": null,
31 "type": 5,
32 },
33 ]
@@ -44,18 +47,21 @@ Array [
47 "displayName": "Grandparent",
48 "hocDisplayNames": null,
49 "id": 2,
50 + "key": null,
51 "type": 5,
52 },
53 Object {
54 "displayName": "Parent",
55 "hocDisplayNames": null,
56 "id": 3,
57 + "key": null,
58 "type": 5,
59 },
60 Object {
61 "displayName": "Child",
62 "hocDisplayNames": null,
63 "id": 4,
64 + "key": null,
65 "type": 5,
66 },
67 ]
@@ -67,12 +73,14 @@ Array [
73 "displayName": "Grandparent",
74 "hocDisplayNames": null,
75 "id": 2,
76 + "key": null,
77 "type": 5,
78 },
79 Object {
80 "displayName": "Parent",
81 "hocDisplayNames": null,
82 "id": 3,
83 + "key": null,
84 "type": 5,
85 },
86 ]
@@ -84,6 +92,7 @@ Array [
92 "displayName": "Grandparent",
93 "hocDisplayNames": null,
94 "id": 2,
95 + "key": null,
96 "type": 5,
97 },
98 Object {
@@ -92,6 +101,7 @@ Array [
101 "Memo",
102 ],
103 "id": 3,
104 + "key": null,
105 "type": 8,
106 },
107 Object {
@@ -100,6 +110,7 @@ Array [
110 "ForwardRef",
111 ],
112 "id": 4,
113 + "key": null,
114 "type": 6,
115 },
116 ]
@@ -116,6 +127,7 @@ Array [
127 "displayName": "Grandparent",
128 "hocDisplayNames": null,
129 "id": 2,
130 + "key": null,
131 "type": 5,
132 },
133 ]
packages/react-devtools-shared/src/__tests__/__snapshots__/profilingCache-test.js.snap
+429 -6
@@ -43,6 +43,15 @@ Object {
43 "passiveEffectDuration": null,
44 "priorityLevel": "Normal",
45 "timestamp": 16,
46 + "updaters": Array [
47 + Object {
48 + "displayName": "Anonymous",
49 + "hocDisplayNames": null,
50 + "id": 1,
51 + "key": null,
52 + "type": 11,
53 + },
54 + ],
55 }
56 `;
57
@@ -82,6 +91,15 @@ Object {
91 "passiveEffectDuration": null,
92 "priorityLevel": "Normal",
93 "timestamp": 15,
94 + "updaters": Array [
95 + Object {
96 + "displayName": "Anonymous",
97 + "hocDisplayNames": null,
98 + "id": 1,
99 + "key": null,
100 + "type": 11,
101 + },
102 + ],
103 }
104 `;
105
@@ -110,6 +128,15 @@ Object {
128 "passiveEffectDuration": null,
129 "priorityLevel": "Immediate",
130 "timestamp": 18,
131 + "updaters": Array [
132 + Object {
133 + "displayName": "Anonymous",
134 + "hocDisplayNames": null,
135 + "id": 1,
136 + "key": null,
137 + "type": 11,
138 + },
139 + ],
140 }
141 `;
142
@@ -165,6 +192,15 @@ Object {
192 "passiveEffectDuration": null,
193 "priorityLevel": "Normal",
194 "timestamp": 12,
195 + "updaters": Array [
196 + Object {
197 + "displayName": "Anonymous",
198 + "hocDisplayNames": null,
199 + "id": 1,
200 + "key": null,
201 + "type": 11,
202 + },
203 + ],
204 }
205 `;
206
@@ -222,6 +258,15 @@ Object {
258 "passiveEffectDuration": null,
259 "priorityLevel": "Immediate",
260 "timestamp": 25,
261 + "updaters": Array [
262 + Object {
263 + "displayName": "Anonymous",
264 + "hocDisplayNames": null,
265 + "id": 1,
266 + "key": null,
267 + "type": 11,
268 + },
269 + ],
270 }
271 `;
272
@@ -261,6 +306,15 @@ Object {
306 "passiveEffectDuration": null,
307 "priorityLevel": "Immediate",
308 "timestamp": 35,
309 + "updaters": Array [
310 + Object {
311 + "displayName": "Anonymous",
312 + "hocDisplayNames": null,
313 + "id": 1,
314 + "key": null,
315 + "type": 11,
316 + },
317 + ],
318 }
319 `;
320
@@ -291,6 +345,15 @@ Object {
345 "passiveEffectDuration": null,
346 "priorityLevel": "Immediate",
347 "timestamp": 45,
348 + "updaters": Array [
349 + Object {
350 + "displayName": "Anonymous",
351 + "hocDisplayNames": null,
352 + "id": 1,
353 + "key": null,
354 + "type": 11,
355 + },
356 + ],
357 }
358 `;
359
@@ -392,6 +455,15 @@ Object {
455 "passiveEffectDuration": null,
456 "priorityLevel": "Normal",
457 "timestamp": 12,
458 + "updaters": Array [
459 + Object {
460 + "displayName": "Anonymous",
461 + "hocDisplayNames": null,
462 + "id": 1,
463 + "key": null,
464 + "type": 11,
465 + },
466 + ],
467 },
468 Object {
469 "changeDescriptions": Array [
@@ -488,6 +560,15 @@ Object {
560 "passiveEffectDuration": null,
561 "priorityLevel": "Immediate",
562 "timestamp": 25,
563 + "updaters": Array [
564 + Object {
565 + "displayName": "Anonymous",
566 + "hocDisplayNames": null,
567 + "id": 1,
568 + "key": null,
569 + "type": 11,
570 + },
571 + ],
572 },
573 Object {
574 "changeDescriptions": Array [
@@ -548,6 +629,15 @@ Object {
629 "passiveEffectDuration": null,
630 "priorityLevel": "Immediate",
631 "timestamp": 35,
632 + "updaters": Array [
633 + Object {
634 + "displayName": "Anonymous",
635 + "hocDisplayNames": null,
636 + "id": 1,
637 + "key": null,
638 + "type": 11,
639 + },
640 + ],
641 },
642 Object {
643 "changeDescriptions": Array [
@@ -590,6 +680,15 @@ Object {
680 "passiveEffectDuration": null,
681 "priorityLevel": "Immediate",
682 "timestamp": 45,
683 + "updaters": Array [
684 + Object {
685 + "displayName": "Anonymous",
686 + "hocDisplayNames": null,
687 + "id": 1,
688 + "key": null,
689 + "type": 11,
690 + },
691 + ],
692 },
693 ],
694 "displayName": "Parent",
@@ -736,7 +835,7 @@ Object {
835 "snapshots": Array [],
836 },
837 ],
739 - "version": 4,
838 + "version": 5,
839 }
840 `;
841
@@ -855,6 +954,15 @@ Object {
954 "passiveEffectDuration": null,
955 "priorityLevel": "Normal",
956 "timestamp": 11,
957 + "updaters": Array [
958 + Object {
959 + "displayName": "Anonymous",
960 + "hocDisplayNames": null,
961 + "id": 1,
962 + "key": null,
963 + "type": 11,
964 + },
965 + ],
966 },
967 Object {
968 "changeDescriptions": Array [
@@ -933,6 +1041,15 @@ Object {
1041 "passiveEffectDuration": null,
1042 "priorityLevel": "Immediate",
1043 "timestamp": 22,
1044 + "updaters": Array [
1045 + Object {
1046 + "displayName": "Anonymous",
1047 + "hocDisplayNames": null,
1048 + "id": 1,
1049 + "key": null,
1050 + "type": 11,
1051 + },
1052 + ],
1053 },
1054 Object {
1055 "changeDescriptions": Array [
@@ -1029,6 +1146,15 @@ Object {
1146 "passiveEffectDuration": null,
1147 "priorityLevel": "Immediate",
1148 "timestamp": 35,
1149 + "updaters": Array [
1150 + Object {
1151 + "displayName": "Anonymous",
1152 + "hocDisplayNames": null,
1153 + "id": 1,
1154 + "key": null,
1155 + "type": 11,
1156 + },
1157 + ],
1158 },
1159 ],
1160 "displayName": "Parent",
@@ -1170,7 +1296,7 @@ Object {
1296 "snapshots": Array [],
1297 },
1298 ],
1173 - "version": 4,
1299 + "version": 5,
1300 }
1301 `;
1302
@@ -1230,6 +1356,15 @@ Object {
1356 "passiveEffectDuration": null,
1357 "priorityLevel": "Immediate",
1358 "timestamp": 13,
1359 + "updaters": Array [
1360 + Object {
1361 + "displayName": "Anonymous",
1362 + "hocDisplayNames": null,
1363 + "id": 1,
1364 + "key": null,
1365 + "type": 11,
1366 + },
1367 + ],
1368 },
1369 Object {
1370 "changeDescriptions": Map {
@@ -1266,6 +1401,15 @@ Object {
1401 "passiveEffectDuration": null,
1402 "priorityLevel": "Immediate",
1403 "timestamp": 34,
1404 + "updaters": Array [
1405 + Object {
1406 + "displayName": "Anonymous",
1407 + "hocDisplayNames": null,
1408 + "id": 1,
1409 + "key": null,
1410 + "type": 11,
1411 + },
1412 + ],
1413 },
1414 Object {
1415 "changeDescriptions": Map {
@@ -1293,6 +1437,15 @@ Object {
1437 "passiveEffectDuration": null,
1438 "priorityLevel": "Immediate",
1439 "timestamp": 44,
1440 + "updaters": Array [
1441 + Object {
1442 + "displayName": "Anonymous",
1443 + "hocDisplayNames": null,
1444 + "id": 1,
1445 + "key": null,
1446 + "type": 11,
1447 + },
1448 + ],
1449 },
1450 ],
1451 "displayName": "Parent",
@@ -1470,6 +1623,15 @@ Object {
1623 "passiveEffectDuration": null,
1624 "priorityLevel": "Normal",
1625 "timestamp": 24,
1626 + "updaters": Array [
1627 + Object {
1628 + "displayName": "Anonymous",
1629 + "hocDisplayNames": null,
1630 + "id": 11,
1631 + "key": null,
1632 + "type": 11,
1633 + },
1634 + ],
1635 },
1636 ],
1637 "displayName": "Parent",
@@ -1554,6 +1716,15 @@ Object {
1716 "passiveEffectDuration": null,
1717 "priorityLevel": "Normal",
1718 "timestamp": 34,
1719 + "updaters": Array [
1720 + Object {
1721 + "displayName": "Anonymous",
1722 + "hocDisplayNames": null,
1723 + "id": 6,
1724 + "key": null,
1725 + "type": 11,
1726 + },
1727 + ],
1728 },
1729 ],
1730 "displayName": "Parent",
@@ -1723,6 +1894,15 @@ Object {
1894 "passiveEffectDuration": null,
1895 "priorityLevel": "Immediate",
1896 "timestamp": 13,
1897 + "updaters": Array [
1898 + Object {
1899 + "displayName": "Anonymous",
1900 + "hocDisplayNames": null,
1901 + "id": 1,
1902 + "key": null,
1903 + "type": 11,
1904 + },
1905 + ],
1906 },
1907 Object {
1908 "changeDescriptions": Array [
@@ -1783,6 +1963,15 @@ Object {
1963 "passiveEffectDuration": null,
1964 "priorityLevel": "Immediate",
1965 "timestamp": 34,
1966 + "updaters": Array [
1967 + Object {
1968 + "displayName": "Anonymous",
1969 + "hocDisplayNames": null,
1970 + "id": 1,
1971 + "key": null,
1972 + "type": 11,
1973 + },
1974 + ],
1975 },
1976 Object {
1977 "changeDescriptions": Array [
@@ -1825,6 +2014,15 @@ Object {
2014 "passiveEffectDuration": null,
2015 "priorityLevel": "Immediate",
2016 "timestamp": 44,
2017 + "updaters": Array [
2018 + Object {
2019 + "displayName": "Anonymous",
2020 + "hocDisplayNames": null,
2021 + "id": 1,
2022 + "key": null,
2023 + "type": 11,
2024 + },
2025 + ],
2026 },
2027 ],
2028 "displayName": "Parent",
@@ -2062,6 +2260,15 @@ Object {
2260 "passiveEffectDuration": null,
2261 "priorityLevel": "Normal",
2262 "timestamp": 24,
2263 + "updaters": Array [
2264 + Object {
2265 + "displayName": "Anonymous",
2266 + "hocDisplayNames": null,
2267 + "id": 11,
2268 + "key": null,
2269 + "type": 11,
2270 + },
2271 + ],
2272 },
2273 ],
2274 "displayName": "Parent",
@@ -2143,6 +2350,15 @@ Object {
2350 "passiveEffectDuration": null,
2351 "priorityLevel": "Normal",
2352 "timestamp": 34,
2353 + "updaters": Array [
2354 + Object {
2355 + "displayName": "Anonymous",
2356 + "hocDisplayNames": null,
2357 + "id": 6,
2358 + "key": null,
2359 + "type": 11,
2360 + },
2361 + ],
2362 },
2363 ],
2364 "displayName": "Parent",
@@ -2235,7 +2451,7 @@ Object {
2451 ],
2452 },
2453 ],
2238 - "version": 4,
2454 + "version": 5,
2455 }
2456 `;
2457
@@ -2258,6 +2474,15 @@ Object {
2474 "passiveEffectDuration": null,
2475 "priorityLevel": "Normal",
2476 "timestamp": 0,
2477 + "updaters": Array [
2478 + Object {
2479 + "displayName": "Anonymous",
2480 + "hocDisplayNames": null,
2481 + "id": 1,
2482 + "key": null,
2483 + "type": 11,
2484 + },
2485 + ],
2486 },
2487 ],
2488 "displayName": "Suspense",
@@ -2327,6 +2552,15 @@ Object {
2552 "passiveEffectDuration": null,
2553 "priorityLevel": "Normal",
2554 "timestamp": 0,
2555 + "updaters": Array [
2556 + Object {
2557 + "displayName": "Anonymous",
2558 + "hocDisplayNames": null,
2559 + "id": 1,
2560 + "key": null,
2561 + "type": 11,
2562 + },
2563 + ],
2564 }
2565 `;
2566
@@ -2359,6 +2593,15 @@ Object {
2593 "passiveEffectDuration": null,
2594 "priorityLevel": "Immediate",
2595 "timestamp": 0,
2596 + "updaters": Array [
2597 + Object {
2598 + "displayName": "Anonymous",
2599 + "hocDisplayNames": null,
2600 + "id": 1,
2601 + "key": null,
2602 + "type": 11,
2603 + },
2604 + ],
2605 }
2606 `;
2607
@@ -2385,6 +2628,15 @@ Object {
2628 "passiveEffectDuration": null,
2629 "priorityLevel": "Immediate",
2630 "timestamp": 0,
2631 + "updaters": Array [
2632 + Object {
2633 + "displayName": "Component",
2634 + "hocDisplayNames": null,
2635 + "id": 3,
2636 + "key": null,
2637 + "type": 5,
2638 + },
2639 + ],
2640 }
2641 `;
2642
@@ -2411,6 +2663,15 @@ Object {
2663 "passiveEffectDuration": null,
2664 "priorityLevel": "Immediate",
2665 "timestamp": 0,
2666 + "updaters": Array [
2667 + Object {
2668 + "displayName": "Component",
2669 + "hocDisplayNames": null,
2670 + "id": 3,
2671 + "key": null,
2672 + "type": 5,
2673 + },
2674 + ],
2675 }
2676 `;
2677
@@ -2441,6 +2702,15 @@ Object {
2702 "passiveEffectDuration": null,
2703 "priorityLevel": "Immediate",
2704 "timestamp": 0,
2705 + "updaters": Array [
2706 + Object {
2707 + "displayName": "Anonymous",
2708 + "hocDisplayNames": null,
2709 + "id": 1,
2710 + "key": null,
2711 + "type": 11,
2712 + },
2713 + ],
2714 }
2715 `;
2716
@@ -2496,6 +2766,15 @@ Object {
2766 "passiveEffectDuration": null,
2767 "priorityLevel": "Normal",
2768 "timestamp": 0,
2769 + "updaters": Array [
2770 + Object {
2771 + "displayName": "Anonymous",
2772 + "hocDisplayNames": null,
2773 + "id": 1,
2774 + "key": null,
2775 + "type": 11,
2776 + },
2777 + ],
2778 },
2779 Object {
2780 "changeDescriptions": Array [
@@ -2546,6 +2825,15 @@ Object {
2825 "passiveEffectDuration": null,
2826 "priorityLevel": "Immediate",
2827 "timestamp": 0,
2828 + "updaters": Array [
2829 + Object {
2830 + "displayName": "Anonymous",
2831 + "hocDisplayNames": null,
2832 + "id": 1,
2833 + "key": null,
2834 + "type": 11,
2835 + },
2836 + ],
2837 },
2838 Object {
2839 "changeDescriptions": Array [
@@ -2578,6 +2866,15 @@ Object {
2866 "passiveEffectDuration": null,
2867 "priorityLevel": "Immediate",
2868 "timestamp": 0,
2869 + "updaters": Array [
2870 + Object {
2871 + "displayName": "Component",
2872 + "hocDisplayNames": null,
2873 + "id": 3,
2874 + "key": null,
2875 + "type": 5,
2876 + },
2877 + ],
2878 },
2879 Object {
2880 "changeDescriptions": Array [
@@ -2610,6 +2907,15 @@ Object {
2907 "passiveEffectDuration": null,
2908 "priorityLevel": "Immediate",
2909 "timestamp": 0,
2910 + "updaters": Array [
2911 + Object {
2912 + "displayName": "Component",
2913 + "hocDisplayNames": null,
2914 + "id": 3,
2915 + "key": null,
2916 + "type": 5,
2917 + },
2918 + ],
2919 },
2920 Object {
2921 "changeDescriptions": Array [
@@ -2658,6 +2964,15 @@ Object {
2964 "passiveEffectDuration": null,
2965 "priorityLevel": "Immediate",
2966 "timestamp": 0,
2967 + "updaters": Array [
2968 + Object {
2969 + "displayName": "Anonymous",
2970 + "hocDisplayNames": null,
2971 + "id": 1,
2972 + "key": null,
2973 + "type": 11,
2974 + },
2975 + ],
2976 },
2977 ],
2978 "displayName": "Component",
@@ -2747,7 +3062,7 @@ Object {
3062 "snapshots": Array [],
3063 },
3064 ],
2750 - "version": 4,
3065 + "version": 5,
3066 }
3067 `;
3068
@@ -2814,6 +3129,15 @@ Object {
3129 "passiveEffectDuration": null,
3130 "priorityLevel": "Normal",
3131 "timestamp": 0,
3132 + "updaters": Array [
3133 + Object {
3134 + "displayName": "Anonymous",
3135 + "hocDisplayNames": null,
3136 + "id": 1,
3137 + "key": null,
3138 + "type": 11,
3139 + },
3140 + ],
3141 }
3142 `;
3143
@@ -2886,6 +3210,15 @@ Object {
3210 "passiveEffectDuration": null,
3211 "priorityLevel": "Immediate",
3212 "timestamp": 0,
3213 + "updaters": Array [
3214 + Object {
3215 + "displayName": "LegacyContextProvider",
3216 + "hocDisplayNames": null,
3217 + "id": 2,
3218 + "key": null,
3219 + "type": 1,
3220 + },
3221 + ],
3222 }
3223 `;
3224
@@ -2954,6 +3287,15 @@ Object {
3287 "passiveEffectDuration": null,
3288 "priorityLevel": "Immediate",
3289 "timestamp": 0,
3290 + "updaters": Array [
3291 + Object {
3292 + "displayName": "Anonymous",
3293 + "hocDisplayNames": null,
3294 + "id": 1,
3295 + "key": null,
3296 + "type": 11,
3297 + },
3298 + ],
3299 }
3300 `;
3301
@@ -3023,6 +3365,15 @@ Object {
3365 "passiveEffectDuration": null,
3366 "priorityLevel": "Immediate",
3367 "timestamp": 0,
3368 + "updaters": Array [
3369 + Object {
3370 + "displayName": "Anonymous",
3371 + "hocDisplayNames": null,
3372 + "id": 1,
3373 + "key": null,
3374 + "type": 11,
3375 + },
3376 + ],
3377 }
3378 `;
3379
@@ -3091,6 +3442,15 @@ Object {
3442 "passiveEffectDuration": null,
3443 "priorityLevel": "Immediate",
3444 "timestamp": 0,
3445 + "updaters": Array [
3446 + Object {
3447 + "displayName": "Anonymous",
3448 + "hocDisplayNames": null,
3449 + "id": 1,
3450 + "key": null,
3451 + "type": 11,
3452 + },
3453 + ],
3454 }
3455 `;
3456
@@ -3218,6 +3578,15 @@ Object {
3578 "passiveEffectDuration": null,
3579 "priorityLevel": "Normal",
3580 "timestamp": 0,
3581 + "updaters": Array [
3582 + Object {
3583 + "displayName": "Anonymous",
3584 + "hocDisplayNames": null,
3585 + "id": 1,
3586 + "key": null,
3587 + "type": 11,
3588 + },
3589 + ],
3590 },
3591 Object {
3592 "changeDescriptions": Array [
@@ -3338,6 +3707,15 @@ Object {
3707 "passiveEffectDuration": null,
3708 "priorityLevel": "Immediate",
3709 "timestamp": 0,
3710 + "updaters": Array [
3711 + Object {
3712 + "displayName": "LegacyContextProvider",
3713 + "hocDisplayNames": null,
3714 + "id": 2,
3715 + "key": null,
3716 + "type": 1,
3717 + },
3718 + ],
3719 },
3720 Object {
3721 "changeDescriptions": Array [
@@ -3460,6 +3838,15 @@ Object {
3838 "passiveEffectDuration": null,
3839 "priorityLevel": "Immediate",
3840 "timestamp": 0,
3841 + "updaters": Array [
3842 + Object {
3843 + "displayName": "Anonymous",
3844 + "hocDisplayNames": null,
3845 + "id": 1,
3846 + "key": null,
3847 + "type": 11,
3848 + },
3849 + ],
3850 },
3851 Object {
3852 "changeDescriptions": Array [
@@ -3583,6 +3970,15 @@ Object {
3970 "passiveEffectDuration": null,
3971 "priorityLevel": "Immediate",
3972 "timestamp": 0,
3973 + "updaters": Array [
3974 + Object {
3975 + "displayName": "Anonymous",
3976 + "hocDisplayNames": null,
3977 + "id": 1,
3978 + "key": null,
3979 + "type": 11,
3980 + },
3981 + ],
3982 },
3983 Object {
3984 "changeDescriptions": Array [
@@ -3705,6 +4101,15 @@ Object {
4101 "passiveEffectDuration": null,
4102 "priorityLevel": "Immediate",
4103 "timestamp": 0,
4104 + "updaters": Array [
4105 + Object {
4106 + "displayName": "Anonymous",
4107 + "hocDisplayNames": null,
4108 + "id": 1,
4109 + "key": null,
4110 + "type": 11,
4111 + },
4112 + ],
4113 },
4114 ],
4115 "displayName": "LegacyContextProvider",
@@ -3917,7 +4322,7 @@ Object {
4322 "snapshots": Array [],
4323 },
4324 ],
3920 - "version": 4,
4325 + "version": 5,
4326 }
4327 `;
4328
@@ -4020,6 +4425,15 @@ Object {
4425 "passiveEffectDuration": null,
4426 "priorityLevel": "Normal",
4427 "timestamp": 11,
4428 + "updaters": Array [
4429 + Object {
4430 + "displayName": "Anonymous",
4431 + "hocDisplayNames": null,
4432 + "id": 1,
4433 + "key": null,
4434 + "type": 11,
4435 + },
4436 + ],
4437 },
4438 Object {
4439 "changeDescriptions": Array [
@@ -4100,6 +4514,15 @@ Object {
4514 "passiveEffectDuration": null,
4515 "priorityLevel": "Immediate",
4516 "timestamp": 22,
4517 + "updaters": Array [
4518 + Object {
4519 + "displayName": "Anonymous",
4520 + "hocDisplayNames": null,
4521 + "id": 1,
4522 + "key": null,
4523 + "type": 11,
4524 + },
4525 + ],
4526 },
4527 ],
4528 "displayName": "Parent",
@@ -4237,6 +4660,6 @@ Object {
4660 "snapshots": Array [],
4661 },
4662 ],
4240 - "version": 4,
4663 + "version": 5,
4664 }
4665 `;
packages/react-devtools-shared/src/__tests__/profilingUtils-test.js
+1 -1
@@ -22,6 +22,6 @@ describe('profiling utils', () => {
22 dataForRoots: [],
23 }: any),
24 ),
25 - ).toThrow('Unsupported profiler export version "0"');
25 + ).toThrow('Unsupported profile export version');
26 });
27 });
packages/react-devtools-shared/src/backend/legacy/renderer.js
+3 -2
@@ -51,7 +51,7 @@ import type {
51 ComponentFilter,
52 ElementType,
53 } from 'react-devtools-shared/src/types';
54 -import type {Owner, InspectedElement} from '../types';
54 +import type {InspectedElement, SerializedElement} from '../types';
55
56 export type InternalInstance = Object;
57 type LegacyRenderer = Object;
@@ -767,6 +767,7 @@ export function attach(
767 owners.push({
768 displayName: getData(owner).displayName || 'Unknown',
769 id: getID(owner),
770 + key: element.key,
771 type: getElementType(owner),
772 });
773 if (owner._currentElement) {
@@ -1047,7 +1048,7 @@ export function attach(
1048 // Not implemented.
1049 }
1050
1050 - function getOwnersList(id: number): Array<Owner> | null {
1051 + function getOwnersList(id: number): Array<SerializedElement> | null {
1052 // Not implemented.
1053 return null;
1054 }
packages/react-devtools-shared/src/backend/renderer.js
+28 -21
@@ -81,6 +81,8 @@ import {
81 } from './ReactSymbols';
82 import {format} from './utils';
83 import {enableProfilerChangedHookIndices} from 'react-devtools-feature-flags';
84 +import is from 'shared/objectIs';
85 +import isArray from 'shared/isArray';
86
87 import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
88 import type {
@@ -91,13 +93,13 @@ import type {
93 InspectedElementPayload,
94 InstanceAndStyle,
95 NativeType,
94 - Owner,
96 PathFrame,
97 PathMatch,
98 ProfilingDataBackend,
99 ProfilingDataForRootBackend,
100 ReactRenderer,
101 RendererInterface,
102 + SerializedElement,
103 WorkTagMap,
104 } from './types';
105 import type {Interaction} from 'react-devtools-shared/src/devtools/views/Profiler/types';
@@ -105,8 +107,6 @@ import type {
107 ComponentFilter,
108 ElementType,
109 } from 'react-devtools-shared/src/types';
108 -import is from 'shared/objectIs';
109 -import isArray from 'shared/isArray';
110
111 type getDisplayNameForFiberType = (fiber: Fiber) => string | null;
112 type getTypeSymbolType = (type: any) => Symbol | number;
@@ -2172,6 +2172,7 @@ export function attach(
2172 ),
2173 maxActualDuration: 0,
2174 priorityLevel: null,
2175 + updaters: getUpdatersList(root),
2176 effectDuration: null,
2177 passiveEffectDuration: null,
2178 };
@@ -2184,6 +2185,12 @@ export function attach(
2185 }
2186 }
2187
2188 + function getUpdatersList(root): Array<SerializedElement> | null {
2189 + return root.memoizedUpdaters != null
2190 + ? Array.from(root.memoizedUpdaters).map(fiberToSerializedElement)
2191 + : null;
2192 + }
2193 +
2194 function handleCommitFiberUnmount(fiber) {
2195 // This is not recursive.
2196 // We can't traverse fibers after unmounting so instead
@@ -2241,6 +2248,8 @@ export function attach(
2248 priorityLevel:
2249 priorityLevel == null ? null : formatPriorityLevel(priorityLevel),
2250
2251 + updaters: getUpdatersList(root),
2252 +
2253 // Initialize to null; if new enough React version is running,
2254 // these values will be read during separate handlePostCommitFiberRoot() call.
2255 effectDuration: null,
@@ -2637,7 +2646,16 @@ export function attach(
2646 }
2647 }
2648
2640 - function getOwnersList(id: number): Array<Owner> | null {
2649 + function fiberToSerializedElement(fiber: Fiber): SerializedElement {
2650 + return {
2651 + displayName: getDisplayNameForFiber(fiber) || 'Anonymous',
2652 + id: getFiberID(getPrimaryFiber(fiber)),
2653 + key: fiber.key,
2654 + type: getElementTypeForFiber(fiber),
2655 + };
2656 + }
2657 +
2658 + function getOwnersList(id: number): Array<SerializedElement> | null {
2659 const fiber = findCurrentFiberUsingSlowPathById(id);
2660 if (fiber == null) {
2661 return null;
@@ -2645,22 +2663,12 @@ export function attach(
2663
2664 const {_debugOwner} = fiber;
2665
2648 - const owners = [
2649 - {
2650 - displayName: getDisplayNameForFiber(fiber) || 'Anonymous',
2651 - id,
2652 - type: getElementTypeForFiber(fiber),
2653 - },
2654 - ];
2666 + const owners: Array<SerializedElement> = [fiberToSerializedElement(fiber)];
2667
2668 if (_debugOwner) {
2669 let owner = _debugOwner;
2670 while (owner !== null) {
2659 - owners.unshift({
2660 - displayName: getDisplayNameForFiber(owner) || 'Anonymous',
2661 - id: getFiberID(getPrimaryFiber(owner)),
2662 - type: getElementTypeForFiber(owner),
2663 - });
2671 + owners.unshift(fiberToSerializedElement(owner));
2672 owner = owner._debugOwner || null;
2673 }
2674 }
@@ -2791,11 +2799,7 @@ export function attach(
2799 owners = [];
2800 let owner = _debugOwner;
2801 while (owner !== null) {
2794 - owners.push({
2795 - displayName: getDisplayNameForFiber(owner) || 'Anonymous',
2796 - id: getFiberID(getPrimaryFiber(owner)),
2797 - type: getElementTypeForFiber(owner),
2798 - });
2802 + owners.push(fiberToSerializedElement(owner));
2803 owner = owner._debugOwner || null;
2804 }
2805 }
@@ -3380,6 +3384,7 @@ export function attach(
3384 maxActualDuration: number,
3385 passiveEffectDuration: number | null,
3386 priorityLevel: string | null,
3387 + updaters: Array<SerializedElement> | null,
3388 |};
3389
3390 type CommitProfilingMetadataMap = Map<number, Array<CommitProfilingData>>;
@@ -3438,6 +3443,7 @@ export function attach(
3443 passiveEffectDuration,
3444 priorityLevel,
3445 commitTime,
3446 + updaters,
3447 } = commitProfilingData;
3448
3449 const interactionIDs: Array<number> = [];
@@ -3478,6 +3484,7 @@ export function attach(
3484 passiveEffectDuration,
3485 priorityLevel,
3486 timestamp: commitTime,
3487 + updaters,
3488 });
3489 });
3490
packages/react-devtools-shared/src/backend/types.js
+6 -4
@@ -168,6 +168,7 @@ export type CommitDataBackend = {|
168 passiveEffectDuration: number | null,
169 priorityLevel: string | null,
170 timestamp: number,
171 + updaters: Array<SerializedElement> | null,
172 |};
173
174 export type ProfilingDataForRootBackend = {|
@@ -199,15 +200,16 @@ export type PathMatch = {|
200 isFullMatch: boolean,
201 |};
202
202 -export type Owner = {|
203 +export type SerializedElement = {|
204 displayName: string | null,
205 id: number,
206 + key: number | string | null,
207 type: ElementType,
208 |};
209
210 export type OwnersList = {|
211 id: number,
210 - owners: Array<Owner> | null,
212 + owners: Array<SerializedElement> | null,
213 |};
214
215 export type InspectedElement = {|
@@ -244,7 +246,7 @@ export type InspectedElement = {|
246 warnings: Array<[string, number]>,
247
248 // List of owners
247 - owners: Array<Owner> | null,
249 + owners: Array<SerializedElement> | null,
250
251 // Location of component in source code.
252 source: Source | null,
@@ -322,7 +324,7 @@ export type RendererInterface = {
324 getDisplayNameForFiberID: GetDisplayNameForFiberID,
325 getInstanceAndStyle(id: number): InstanceAndStyle,
326 getProfilingData(): ProfilingDataBackend,
325 - getOwnersList: (id: number) => Array<Owner> | null,
327 + getOwnersList: (id: number) => Array<SerializedElement> | null,
328 getPathForElement: (id: number) => Array<PathFrame> | null,
329 handleCommitFiberRoot: (fiber: Object, commitPriority?: number) => void,
330 handleCommitFiberUnmount: (fiber: Object) => void,
packages/react-devtools-shared/src/constants.js
+1 -1
@@ -41,7 +41,7 @@ export const LOCAL_STORAGE_SHOW_INLINE_WARNINGS_AND_ERRORS_KEY =
41 export const LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY =
42 'React::DevTools::traceUpdatesEnabled';
43
44 -export const PROFILER_EXPORT_VERSION = 4;
44 +export const PROFILER_EXPORT_VERSION = 5;
45
46 export const CHANGE_LOG_URL =
47 'https://github.com/facebook/react/blob/master/packages/react-devtools/CHANGELOG.md';
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementView.js
+2 -2
@@ -35,7 +35,7 @@ import {
35 import styles from './InspectedElementView.css';
36
37 import type {ContextMenuContextType} from '../context';
38 -import type {Element, InspectedElement, Owner} from './types';
38 +import type {Element, InspectedElement, SerializedElement} from './types';
39 import type {ElementType} from 'react-devtools-shared/src/types';
40
41 export type CopyPath = (path: Array<string | number>) => void;
@@ -127,7 +127,7 @@ export default function InspectedElementView({
127 <div className={styles.Owners}>
128 <div className={styles.OwnersHeader}>rendered by</div>
129 {showOwnersList &&
130 - ((owners: any): Array<Owner>).map(owner => (
130 + ((owners: any): Array<SerializedElement>).map(owner => (
131 <OwnerView
132 key={owner.id}
133 displayName={owner.displayName || 'Anonymous'}
packages/react-devtools-shared/src/devtools/views/Components/OwnersListContext.js
+9 -5
@@ -17,23 +17,27 @@ import {separateDisplayNameAndHOCs} from 'react-devtools-shared/src/utils';
17 import type {OwnersList} from 'react-devtools-shared/src/backend/types';
18 import type {
19 Element,
20 - Owner,
20 + SerializedElement,
21 } from 'react-devtools-shared/src/devtools/views/Components/types';
22 import type {Resource, Thenable} from '../../cache';
23
24 -type Context = (id: number) => Array<Owner> | null;
24 +type Context = (id: number) => Array<SerializedElement> | null;
25
26 const OwnersListContext = createContext<Context>(((null: any): Context));
27 OwnersListContext.displayName = 'OwnersListContext';
28
29 -type ResolveFn = (ownersList: Array<Owner> | null) => void;
29 +type ResolveFn = (ownersList: Array<SerializedElement> | null) => void;
30 type InProgressRequest = {|
31 - promise: Thenable<Array<Owner>>,
31 + promise: Thenable<Array<SerializedElement>>,
32 resolveFn: ResolveFn,
33 |};
34
35 const inProgressRequests: WeakMap<Element, InProgressRequest> = new WeakMap();
36 -const resource: Resource<Element, Element, Array<Owner>> = createResource(
36 +const resource: Resource<
37 + Element,
38 + Element,
39 + Array<SerializedElement>,
40 +> = createResource(
41 (element: Element) => {
42 const request = inProgressRequests.get(element);
43 if (request != null) {
packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js
+8 -8
@@ -27,16 +27,16 @@ import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
27 import {useIsOverflowing} from '../hooks';
28 import {StoreContext} from '../context';
29
30 -import type {Owner} from './types';
30 +import type {SerializedElement} from './types';
31
32 import styles from './OwnersStack.css';
33
34 -type SelectOwner = (owner: Owner | null) => void;
34 +type SelectOwner = (owner: SerializedElement | null) => void;
35
36 type ACTION_UPDATE_OWNER_ID = {|
37 type: 'UPDATE_OWNER_ID',
38 ownerID: number | null,
39 - owners: Array<Owner>,
39 + owners: Array<SerializedElement>,
40 |};
41 type ACTION_UPDATE_SELECTED_INDEX = {|
42 type: 'UPDATE_SELECTED_INDEX',
@@ -47,7 +47,7 @@ type Action = ACTION_UPDATE_OWNER_ID | ACTION_UPDATE_SELECTED_INDEX;
47
48 type State = {|
49 ownerID: number | null,
50 - owners: Array<Owner>,
50 + owners: Array<SerializedElement>,
51 selectedIndex: number,
52 |};
53
@@ -104,7 +104,7 @@ export default function OwnerStack() {
104 const {owners, selectedIndex} = state;
105
106 const selectOwner = useCallback<SelectOwner>(
107 - (owner: Owner | null) => {
107 + (owner: SerializedElement | null) => {
108 if (owner !== null) {
109 const index = owners.indexOf(owner);
110 dispatch({
@@ -197,7 +197,7 @@ export default function OwnerStack() {
197 }
198
199 type ElementsDropdownProps = {
200 - owners: Array<Owner>,
200 + owners: Array<SerializedElement>,
201 selectedIndex: number,
202 selectOwner: SelectOwner,
203 ...
@@ -245,7 +245,7 @@ function ElementsDropdown({
245
246 type ElementViewProps = {
247 isSelected: boolean,
248 - owner: Owner,
248 + owner: SerializedElement,
249 selectOwner: SelectOwner,
250 ...
251 };
@@ -278,7 +278,7 @@ function ElementView({isSelected, owner, selectOwner}: ElementViewProps) {
278 }
279
280 type BackToOwnerButtonProps = {|
281 - owners: Array<Owner>,
281 + owners: Array<SerializedElement>,
282 selectedIndex: number,
283 selectOwner: SelectOwner,
284 |};
packages/react-devtools-shared/src/devtools/views/Components/types.js
+4 -3
@@ -44,16 +44,17 @@ export type Element = {|
44 weight: number,
45 |};
46
47 -export type Owner = {|
47 +export type SerializedElement = {|
48 displayName: string | null,
49 id: number,
50 + key: number | string | null,
51 hocDisplayNames: Array<string> | null,
52 type: ElementType,
53 |};
54
55 export type OwnersList = {|
56 id: number,
56 - owners: Array<Owner> | null,
57 + owners: Array<SerializedElement> | null,
58 |};
59
60 export type InspectedElementResponseType =
@@ -94,7 +95,7 @@ export type InspectedElement = {|
95 warnings: Array<[string, number]>,
96
97 // List of owners
97 - owners: Array<Owner> | null,
98 + owners: Array<SerializedElement> | null,
99
100 // Location of component in source code.
101 source: Source | null,
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarCommitInfo.css
+5
@@ -30,6 +30,7 @@
30 .Interactions {
31 margin: 0 0 0.5rem;
32 }
33 +.NoInteractions,
34 .Interaction {
35 display: block;
36 width: 100%;
@@ -45,6 +46,10 @@
46 background-color: var(--color-background-hover);
47 }
48
49 +.NoInteractions {
50 + color: var(--color-dim);
51 +}
52 +
53 .Label {
54 overflow: hidden;
55 text-overflow: ellipsis;
packages/react-devtools-shared/src/devtools/views/Profiler/SidebarCommitInfo.js
+20 -1
@@ -10,8 +10,10 @@
10 import * as React from 'react';
11 import {Fragment, useContext} from 'react';
12 import {ProfilerContext} from './ProfilerContext';
13 +import Updaters from './Updaters';
14 import {formatDuration, formatTime} from './utils';
15 import {StoreContext} from '../context';
16 +import {getCommitTree} from './CommitTreeBuilder';
17
18 import styles from './SidebarCommitInfo.css';
19
@@ -39,6 +41,7 @@ export default function SidebarCommitInfo(_: Props) {
41 passiveEffectDuration,
42 priorityLevel,
43 timestamp,
44 + updaters,
45 } = profilerStore.getCommitData(rootID, selectedCommitIndex);
46
47 const viewInteraction = interactionID => {
@@ -49,6 +52,15 @@ export default function SidebarCommitInfo(_: Props) {
52 const hasCommitPhaseDurations =
53 effectDuration !== null || passiveEffectDuration !== null;
54
55 + const commitTree =
56 + updaters !== null
57 + ? getCommitTree({
58 + commitIndex: selectedCommitIndex,
59 + profilerStore,
60 + rootID,
61 + })
62 + : null;
63 +
64 return (
65 <Fragment>
66 <div className={styles.Toolbar}>Commit information</div>
@@ -102,11 +114,18 @@ export default function SidebarCommitInfo(_: Props) {
114 </li>
115 )}
116
117 + {updaters !== null && commitTree !== null && (
118 + <li className={styles.ListItem}>
119 + <label className={styles.Label}>What caused this update</label>?
120 + <Updaters commitTree={commitTree} updaters={updaters} />
121 + </li>
122 + )}
123 +
124 <li className={styles.Interactions}>
125 <label className={styles.Label}>Interactions</label>:
126 <div className={styles.InteractionList}>
127 {interactionIDs.length === 0 ? (
109 - <div className={styles.NoInteractions}>None</div>
128 + <div className={styles.NoInteractions}>(none)</div>
129 ) : null}
130 {interactionIDs.map(interactionID => {
131 const interaction = interactions.get(interactionID);
packages/react-devtools-shared/src/devtools/views/Profiler/Updaters.css new
+25
@@ -0,0 +1,25 @@
1 +.Updaters {
2 + margin: 0 0 0.5rem;
3 +}
4 +
5 +.NoUpdaters,
6 +.Updater,
7 +.UnmountedUpdater {
8 + display: block;
9 + width: 100%;
10 + text-align: left;
11 + background: none;
12 + border: none;
13 + padding: 0.25rem 0.5rem;
14 + color: var(--color-text);
15 +}
16 +.Updater:focus,
17 +.Updater:hover {
18 + outline: none;
19 + background-color: var(--color-background-hover);
20 +}
21 +
22 +.NoUpdaters,
23 +.UnmountedUpdater {
24 + color: var(--color-dim);
25 +}
packages/react-devtools-shared/src/devtools/views/Profiler/Updaters.js new
+55
@@ -0,0 +1,55 @@
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 + * @flow
8 + */
9 +
10 +import type {CommitTree} from './types';
11 +import type {SerializedElement} from '../Components/types';
12 +
13 +import * as React from 'react';
14 +import {useContext} from 'react';
15 +import {ProfilerContext} from './ProfilerContext';
16 +import styles from './Updaters.css';
17 +
18 +export type Props = {|
19 + commitTree: CommitTree,
20 + updaters: Array<SerializedElement>,
21 +|};
22 +
23 +export default function Updaters({commitTree, updaters}: Props) {
24 + const {selectFiber} = useContext(ProfilerContext);
25 +
26 + const children =
27 + updaters.length > 0 ? (
28 + updaters.map<React$Node>((serializedElement: SerializedElement) => {
29 + const {displayName, id, key} = serializedElement;
30 + const isVisibleInTree = commitTree.nodes.has(id);
31 + if (isVisibleInTree) {
32 + return (
33 + <button
34 + key={id}
35 + className={styles.Updater}
36 + onClick={() => selectFiber(id, displayName)}>
37 + {displayName} {key ? `key="${key}"` : ''}
38 + </button>
39 + );
40 + } else {
41 + return (
42 + <div key={id} className={styles.UnmountedUpdater}>
43 + {displayName} {key ? `key="${key}"` : ''}
44 + </div>
45 + );
46 + }
47 + })
48 + ) : (
49 + <div key="none" className={styles.NoUpdaters}>
50 + (unknown)
51 + </div>
52 + );
53 +
54 + return <div className={styles.Updaters}>{children}</div>;
55 +}
packages/react-devtools-shared/src/devtools/views/Profiler/types.js
+6 -1
@@ -8,6 +8,7 @@
8 */
9
10 import type {ElementType} from 'react-devtools-shared/src/types';
11 +import type {SerializedElement} from '../Components/types';
12
13 export type CommitTreeNode = {|
14 id: number,
@@ -80,6 +81,9 @@ export type CommitDataFrontend = {|
81
82 // When did this commit occur (relative to the start of profiling)
83 timestamp: number,
84 +
85 + // Fiber(s) responsible for scheduling this update.
86 + updaters: Array<SerializedElement> | null,
87 |};
88
89 export type ProfilingDataForRootFrontend = {|
@@ -131,6 +135,7 @@ export type CommitDataExport = {|
135 passiveEffectDuration: number | null,
136 priorityLevel: string | null,
137 timestamp: number,
138 + updaters: Array<SerializedElement> | null,
139 |};
140
141 export type ProfilingDataForRootExport = {|
@@ -148,6 +153,6 @@ export type ProfilingDataForRootExport = {|
153
154 // Serializable version of ProfilingDataFrontend data.
155 export type ProfilingDataExport = {|
151 - version: 4,
156 + version: 5,
157 dataForRoots: Array<ProfilingDataForRootExport>,
158 |};
packages/react-devtools-shared/src/devtools/views/Profiler/utils.js
+25 -1
@@ -8,6 +8,7 @@
8 */
9
10 import {PROFILER_EXPORT_VERSION} from 'react-devtools-shared/src/constants';
11 +import {separateDisplayNameAndHOCs} from 'react-devtools-shared/src/utils';
12
13 import type {ProfilingDataBackend} from 'react-devtools-shared/src/backend/types';
14 import type {
@@ -84,6 +85,23 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
85 passiveEffectDuration: commitDataBackend.passiveEffectDuration,
86 priorityLevel: commitDataBackend.priorityLevel,
87 timestamp: commitDataBackend.timestamp,
88 + updaters:
89 + commitDataBackend.updaters !== null
90 + ? commitDataBackend.updaters.map(serializedElement => {
91 + const [
92 + serializedElementDisplayName,
93 + serializedElementHocDisplayNames,
94 + ] = separateDisplayNameAndHOCs(
95 + serializedElement.displayName,
96 + serializedElement.type,
97 + );
98 + return {
99 + ...serializedElement,
100 + displayName: serializedElementDisplayName,
101 + hocDisplayNames: serializedElementHocDisplayNames,
102 + };
103 + })
104 + : null,
105 }),
106 );
107
@@ -111,7 +129,9 @@ export function prepareProfilingDataFrontendFromExport(
129 const {version} = profilingDataExport;
130
131 if (version !== PROFILER_EXPORT_VERSION) {
114 - throw Error(`Unsupported profiler export version "${version}"`);
132 + throw Error(
133 + `Unsupported profile export version "${version}". Supported version is "${PROFILER_EXPORT_VERSION}".`,
134 + );
135 }
136
137 const dataForRoots: Map<number, ProfilingDataForRootFrontend> = new Map();
@@ -138,6 +158,7 @@ export function prepareProfilingDataFrontendFromExport(
158 passiveEffectDuration,
159 priorityLevel,
160 timestamp,
161 + updaters,
162 }) => ({
163 changeDescriptions:
164 changeDescriptions != null ? new Map(changeDescriptions) : null,
@@ -149,6 +170,7 @@ export function prepareProfilingDataFrontendFromExport(
170 passiveEffectDuration,
171 priorityLevel,
172 timestamp,
173 + updaters,
174 }),
175 ),
176 displayName,
@@ -193,6 +215,7 @@ export function prepareProfilingDataExport(
215 passiveEffectDuration,
216 priorityLevel,
217 timestamp,
218 + updaters,
219 }) => ({
220 changeDescriptions:
221 changeDescriptions != null
@@ -206,6 +229,7 @@ export function prepareProfilingDataExport(
229 passiveEffectDuration,
230 priorityLevel,
231 timestamp,
232 + updaters,
233 }),
234 ),
235 displayName,