@@ -20,31 +20,62 @@ import getComponentName from 'shared/getComponentName';
20
20
* require.
21
21
*/
22
22
const supportsUserTiming =
23
- typeof performance !== 'undefined' && typeof performance . mark === 'function' ;
23
+ typeof performance !== 'undefined' &&
24
+ typeof performance . mark === 'function' &&
25
+ typeof performance . clearMarks === 'function' ;
26
+
27
+ let supportsUserTimingV3 = false ;
28
+ if ( supportsUserTiming ) {
29
+ const CHECK_V3_MARK = '__v3' ;
30
+ const markOptions = { } ;
31
+ // $FlowFixMe: Ignore Flow complaining about needing a value
32
+ Object . defineProperty ( markOptions , 'startTime' , {
33
+ get : function ( ) {
34
+ supportsUserTimingV3 = true ;
35
+ return 0 ;
36
+ } ,
37
+ set : function ( ) { } ,
38
+ } ) ;
39
+
40
+ try {
41
+ // $FlowFixMe: Flow expects the User Timing level 2 API.
42
+ performance . mark ( CHECK_V3_MARK , markOptions ) ;
43
+ } catch ( error ) {
44
+ // Ignore
45
+ } finally {
46
+ performance . clearMarks ( CHECK_V3_MARK ) ;
47
+ }
48
+ }
24
49
25
50
function formatLanes ( laneOrLanes : Lane | Lanes ) : string {
26
51
return ( ( laneOrLanes : any ) : number ) . toString ( ) ;
27
52
}
28
53
29
54
// Create a mark on React initialization
30
55
if ( enableSchedulingProfiler ) {
31
- if ( supportsUserTiming ) {
32
- performance . mark ( `--react-init-${ ReactVersion } ` ) ;
56
+ if ( supportsUserTimingV3 ) {
57
+ const name = `--react-init-${ ReactVersion } ` ;
58
+ performance . mark ( name ) ;
59
+ performance . clearMarks ( name ) ;
33
60
}
34
61
}
35
62
36
63
export function markCommitStarted ( lanes : Lanes ) : void {
37
64
if ( enableSchedulingProfiler ) {
38
- if ( supportsUserTiming ) {
39
- performance . mark ( `--commit-start-${ formatLanes ( lanes ) } ` ) ;
65
+ if ( supportsUserTimingV3 ) {
66
+ const name = `--commit-start-${ formatLanes ( lanes ) } ` ;
67
+ performance . mark ( name ) ;
68
+ performance . clearMarks ( name ) ;
40
69
}
41
70
}
42
71
}
43
72
44
73
export function markCommitStopped ( ) : void {
45
74
if ( enableSchedulingProfiler ) {
46
- if ( supportsUserTiming ) {
47
- performance . mark ( '--commit-stop' ) ;
75
+ if ( supportsUserTimingV3 ) {
76
+ const name = '--commit-stop' ;
77
+ performance . mark ( name ) ;
78
+ performance . clearMarks ( name ) ;
48
79
}
49
80
}
50
81
}
@@ -63,103 +94,133 @@ function getWakeableID(wakeable: Wakeable): number {
63
94
64
95
export function markComponentSuspended ( fiber : Fiber , wakeable : Wakeable ) : void {
65
96
if ( enableSchedulingProfiler ) {
66
- if ( supportsUserTiming ) {
97
+ if ( supportsUserTimingV3 ) {
67
98
const id = getWakeableID ( wakeable ) ;
68
99
const componentName = getComponentName ( fiber . type ) || 'Unknown' ;
69
100
// TODO Add component stack id
70
- performance . mark ( `--suspense-suspend-${ id } -${ componentName } ` ) ;
101
+ let name = `--suspense-suspend-${ id } -${ componentName } ` ;
102
+ performance . mark ( name ) ;
103
+ performance . clearMarks ( name ) ;
71
104
wakeable . then (
72
- ( ) => performance . mark ( `--suspense-resolved-${ id } -${ componentName } ` ) ,
73
- ( ) => performance . mark ( `--suspense-rejected-${ id } -${ componentName } ` ) ,
105
+ ( ) => {
106
+ name = `--suspense-resolved-${ id } -${ componentName } ` ;
107
+ performance . mark ( name ) ;
108
+ performance . clearMarks ( name ) ;
109
+ } ,
110
+ ( ) => {
111
+ name = `--suspense-rejected-${ id } -${ componentName } ` ;
112
+ performance . mark ( name ) ;
113
+ performance . clearMarks ( name ) ;
114
+ } ,
74
115
) ;
75
116
}
76
117
}
77
118
}
78
119
79
120
export function markLayoutEffectsStarted ( lanes : Lanes ) : void {
80
121
if ( enableSchedulingProfiler ) {
81
- if ( supportsUserTiming ) {
82
- performance . mark ( `--layout-effects-start-${ formatLanes ( lanes ) } ` ) ;
122
+ if ( supportsUserTimingV3 ) {
123
+ const name = `-- layout - effects - start - $ { formatLanes ( lanes ) } `;
124
+ performance.mark(name);
125
+ performance.clearMarks(name);
83
126
}
84
127
}
85
128
}
86
129
87
130
export function markLayoutEffectsStopped(): void {
88
131
if (enableSchedulingProfiler) {
89
- if ( supportsUserTiming ) {
90
- performance . mark ( '--layout-effects-stop' ) ;
132
+ if (supportsUserTimingV3) {
133
+ const name = '--layout-effects-stop';
134
+ performance.mark(name);
135
+ performance.clearMarks(name);
91
136
}
92
137
}
93
138
}
94
139
95
140
export function markPassiveEffectsStarted(lanes: Lanes): void {
96
141
if (enableSchedulingProfiler) {
97
- if ( supportsUserTiming ) {
98
- performance . mark ( `--passive-effects-start-${ formatLanes ( lanes ) } ` ) ;
142
+ if (supportsUserTimingV3) {
143
+ const name = ` -- passive - effects - start - $ { formatLanes ( lanes ) } `;
144
+ performance.mark(name);
145
+ performance.clearMarks(name);
99
146
}
100
147
}
101
148
}
102
149
103
150
export function markPassiveEffectsStopped(): void {
104
151
if (enableSchedulingProfiler) {
105
- if ( supportsUserTiming ) {
106
- performance . mark ( '--passive-effects-stop' ) ;
152
+ if (supportsUserTimingV3) {
153
+ const name = '--passive-effects-stop';
154
+ performance.mark(name);
155
+ performance.clearMarks(name);
107
156
}
108
157
}
109
158
}
110
159
111
160
export function markRenderStarted(lanes: Lanes): void {
112
161
if (enableSchedulingProfiler) {
113
- if ( supportsUserTiming ) {
114
- performance . mark ( `--render-start-${ formatLanes ( lanes ) } ` ) ;
162
+ if (supportsUserTimingV3) {
163
+ const name = ` -- render - start - $ { formatLanes ( lanes ) } `;
164
+ performance.mark(name);
165
+ performance.clearMarks(name);
115
166
}
116
167
}
117
168
}
118
169
119
170
export function markRenderYielded(): void {
120
171
if (enableSchedulingProfiler) {
121
- if ( supportsUserTiming ) {
122
- performance . mark ( '--render-yield' ) ;
172
+ if (supportsUserTimingV3) {
173
+ const name = '--render-yield';
174
+ performance.mark(name);
175
+ performance.clearMarks(name);
123
176
}
124
177
}
125
178
}
126
179
127
180
export function markRenderStopped(): void {
128
181
if (enableSchedulingProfiler) {
129
- if ( supportsUserTiming ) {
130
- performance . mark ( '--render-stop' ) ;
182
+ if (supportsUserTimingV3) {
183
+ const name = '--render-stop';
184
+ performance.mark(name);
185
+ performance.clearMarks(name);
131
186
}
132
187
}
133
188
}
134
189
135
190
export function markRenderScheduled(lane: Lane): void {
136
191
if (enableSchedulingProfiler) {
137
- if ( supportsUserTiming ) {
138
- performance . mark ( `--schedule-render-${ formatLanes ( lane ) } ` ) ;
192
+ if (supportsUserTimingV3) {
193
+ const name = ` -- schedule - render - $ { formatLanes ( lane ) } `;
194
+ performance.mark(name);
195
+ performance.clearMarks(name);
139
196
}
140
197
}
141
198
}
142
199
143
200
export function markForceUpdateScheduled(fiber: Fiber, lane: Lane): void {
144
201
if (enableSchedulingProfiler) {
145
- if ( supportsUserTiming ) {
202
+ if (supportsUserTimingV3 ) {
146
203
const componentName = getComponentName(fiber.type) || 'Unknown';
147
204
// TODO Add component stack id
148
- performance . mark (
149
- `--schedule-forced-update-${ formatLanes ( lane ) } -${ componentName } ` ,
150
- ) ;
205
+ const name = ` -- schedule - forced - update - $ { formatLanes (
206
+ lane ,
207
+ ) } - $ { componentName} `;
208
+ performance.mark(name);
209
+ performance.clearMarks(name);
151
210
}
152
211
}
153
212
}
154
213
155
214
export function markStateUpdateScheduled(fiber: Fiber, lane: Lane): void {
156
215
if (enableSchedulingProfiler) {
157
- if ( supportsUserTiming ) {
216
+ if (supportsUserTimingV3 ) {
158
217
const componentName = getComponentName(fiber.type) || 'Unknown';
159
218
// TODO Add component stack id
160
- performance . mark (
161
- `--schedule-state-update-${ formatLanes ( lane ) } -${ componentName } ` ,
162
- ) ;
219
+ const name = ` -- schedule - state - update - $ { formatLanes (
220
+ lane ,
221
+ ) } - $ { componentName } `;
222
+ performance . mark ( name ) ;
223
+ performance . clearMarks ( name ) ;
163
224
}
164
225
}
165
226
}
0 commit comments