@@ -29,33 +29,26 @@ import {
2929import {
3030 addValueToProperties ,
3131 addObjectToProperties ,
32+ addObjectDiffToProperties ,
3233} from 'shared/ReactPerformanceTrackProperties' ;
3334
3435import { enableProfilerTimer } from 'shared/ReactFeatureFlags' ;
3536
3637const supportsUserTiming =
3738 enableProfilerTimer &&
3839 typeof console !== 'undefined' &&
39- typeof console . timeStamp === 'function' ;
40+ typeof console . timeStamp === 'function' &&
41+ ( ! __DEV__ ||
42+ // In DEV we also rely on performance.measure
43+ ( typeof performance !== 'undefined' &&
44+ // $FlowFixMe[method-unbinding]
45+ typeof performance . measure === 'function' ) ) ;
4046
4147const COMPONENTS_TRACK = 'Components ⚛' ;
4248const LANES_TRACK_GROUP = 'Scheduler ⚛' ;
4349
4450let currentTrack : string = 'Blocking' ; // Lane
4551
46- const reusableLaneDevToolDetails = {
47- color : 'primary' ,
48- track : 'Blocking' , // Lane
49- trackGroup : LANES_TRACK_GROUP ,
50- } ;
51- const reusableLaneOptions = {
52- start : - 0 ,
53- end : - 0 ,
54- detail : {
55- devtools : reusableLaneDevToolDetails ,
56- } ,
57- } ;
58-
5952export function setCurrentTrackFromLanes ( lanes : Lanes ) : void {
6053 currentTrack = getGroupNameOfHighestPriorityLane ( lanes ) ;
6154}
@@ -166,6 +159,21 @@ export function logComponentDisappeared(
166159 logComponentTrigger ( fiber , startTime , endTime , 'Disconnect' ) ;
167160}
168161
162+ const reusableComponentDevToolDetails = {
163+ color : 'primary' ,
164+ properties : ( null : null | Array < [ string , string ] > ) ,
165+ track : COMPONENTS_TRACK ,
166+ } ;
167+ const reusableComponentOptions = {
168+ start : - 0 ,
169+ end : - 0 ,
170+ detail : {
171+ devtools : reusableComponentDevToolDetails ,
172+ } ,
173+ } ;
174+
175+ const resuableChangedPropsEntry = [ 'Changed Props' , '' ] ;
176+
169177export function logComponentRender (
170178 fiber : Fiber ,
171179 startTime : number ,
@@ -178,8 +186,9 @@ export function logComponentRender(
178186 return ;
179187 }
180188 if ( supportsUserTiming ) {
189+ const alternate = fiber . alternate ;
181190 let selfTime : number = ( fiber . actualDuration : any ) ;
182- if ( fiber . alternate === null || fiber . alternate . child !== fiber . child ) {
191+ if ( alternate === null || alternate . child !== fiber . child ) {
183192 for ( let child = fiber . child ; child !== null ; child = child . sibling ) {
184193 selfTime -= ( child . actualDuration : any ) ;
185194 }
@@ -200,6 +209,36 @@ export function logComponentRender(
200209 : 'error' ;
201210 const debugTask = fiber . _debugTask ;
202211 if ( __DEV__ && debugTask ) {
212+ const props = fiber . memoizedProps ;
213+ if (
214+ props !== null &&
215+ alternate !== null &&
216+ alternate . memoizedProps !== props
217+ ) {
218+ // If this is an update, we'll diff the props and emit which ones changed.
219+ const properties : Array < [ string , string ] > = [ resuableChangedPropsEntry ] ;
220+ addObjectDiffToProperties (
221+ alternate . memoizedProps ,
222+ props ,
223+ properties ,
224+ 0 ,
225+ ) ;
226+ if ( properties . length > 1 ) {
227+ reusableComponentOptions . start = startTime ;
228+ reusableComponentOptions . end = endTime ;
229+ reusableComponentDevToolDetails . color = color ;
230+ reusableComponentDevToolDetails . properties = properties ;
231+ debugTask . run (
232+ // $FlowFixMe[method-unbinding]
233+ performance . measure . bind (
234+ performance ,
235+ name ,
236+ reusableComponentOptions ,
237+ ) ,
238+ ) ;
239+ return ;
240+ }
241+ }
203242 debugTask . run (
204243 // $FlowFixMe[method-unbinding]
205244 console . timeStamp . bind (
@@ -237,12 +276,7 @@ export function logComponentErrored(
237276 // Skip
238277 return ;
239278 }
240- if (
241- __DEV__ &&
242- typeof performance !== 'undefined' &&
243- // $FlowFixMe[method-unbinding]
244- typeof performance . measure === 'function'
245- ) {
279+ if ( __DEV__ ) {
246280 let debugTask : ?ConsoleTask = null ;
247281 const properties : Array < [ string , string ] > = [ ] ;
248282 for ( let i = 0 ; i < errors . length ; i ++ ) {
@@ -267,10 +301,10 @@ export function logComponentErrored(
267301 properties . push ( [ 'Error' , message ] ) ;
268302 }
269303 if ( fiber . key !== null ) {
270- addValueToProperties ( 'key' , fiber . key , properties , 0 ) ;
304+ addValueToProperties ( 'key' , fiber . key , properties , 0 , '' ) ;
271305 }
272306 if ( fiber . memoizedProps !== null ) {
273- addObjectToProperties ( fiber . memoizedProps , properties , 0 ) ;
307+ addObjectToProperties ( fiber . memoizedProps , properties , 0 , '' ) ;
274308 }
275309 if ( debugTask == null ) {
276310 // If the captured values don't have a debug task, fallback to the
@@ -325,12 +359,7 @@ function logComponentEffectErrored(
325359 // Skip
326360 return ;
327361 }
328- if (
329- __DEV__ &&
330- typeof performance !== 'undefined' &&
331- // $FlowFixMe[method-unbinding]
332- typeof performance . measure === 'function'
333- ) {
362+ if ( __DEV__ ) {
334363 const properties : Array < [ string , string ] > = [ ] ;
335364 for ( let i = 0 ; i < errors . length ; i ++ ) {
336365 const capturedValue = errors [ i ] ;
@@ -346,10 +375,10 @@ function logComponentEffectErrored(
346375 properties . push ( [ 'Error' , message ] ) ;
347376 }
348377 if ( fiber . key !== null ) {
349- addValueToProperties ( 'key' , fiber . key , properties , 0 ) ;
378+ addValueToProperties ( 'key' , fiber . key , properties , 0 , '' ) ;
350379 }
351380 if ( fiber . memoizedProps !== null ) {
352- addObjectToProperties ( fiber . memoizedProps , properties , 0 ) ;
381+ addObjectToProperties ( fiber . memoizedProps , properties , 0 , '' ) ;
353382 }
354383 const options = {
355384 start : startTime ,
@@ -815,12 +844,7 @@ export function logRecoveredRenderPhase(
815844 hydrationFailed : boolean ,
816845) : void {
817846 if ( supportsUserTiming ) {
818- if (
819- __DEV__ &&
820- typeof performance !== 'undefined' &&
821- // $FlowFixMe[method-unbinding]
822- typeof performance . measure === 'function'
823- ) {
847+ if ( __DEV__ ) {
824848 const properties : Array < [ string , string ] > = [ ] ;
825849 for ( let i = 0 ; i < recoverableErrors . length ; i ++ ) {
826850 const capturedValue = recoverableErrors [ i ] ;
@@ -939,12 +963,7 @@ export function logCommitErrored(
939963 passive : boolean ,
940964) : void {
941965 if ( supportsUserTiming ) {
942- if (
943- __DEV__ &&
944- typeof performance !== 'undefined' &&
945- // $FlowFixMe[method-unbinding]
946- typeof performance . measure === 'function'
947- ) {
966+ if ( __DEV__ ) {
948967 const properties : Array < [ string , string ] > = [ ] ;
949968 for ( let i = 0 ; i < errors . length ; i ++ ) {
950969 const capturedValue = errors [ i ] ;
@@ -997,8 +1016,6 @@ export function logCommitPhase(
9971016 return ;
9981017 }
9991018 if ( supportsUserTiming ) {
1000- reusableLaneOptions . start = startTime ;
1001- reusableLaneOptions . end = endTime ;
10021019 console . timeStamp (
10031020 'Commit' ,
10041021 startTime ,
0 commit comments