@@ -74,6 +74,11 @@ function popActivity(activity: number | null): void {
7474 ( globalTracingIntegration as any ) . constructor . popActivity ( activity , undefined ) ;
7575}
7676
77+ /**
78+ * Obtain a span given an activity id.
79+ * Is a no-op if invalid Tracing integration.
80+ * @param activity activity id associated with obtained span
81+ */
7782function getActivitySpan ( activity : number | null ) : Span | undefined {
7883 if ( globalTracingIntegration === null ) {
7984 return undefined ;
@@ -86,13 +91,14 @@ function getActivitySpan(activity: number | null): Span | undefined {
8691export type ProfilerProps = {
8792 // The name of the component being profiled.
8893 name : string ;
89- // If the Profiler is disabled. False by default.
94+ // If the Profiler is disabled. False by default. This is useful if you want to disable profilers
95+ // in certain environments.
9096 disabled ?: boolean ;
9197 // If time component is on page should be displayed as spans. False by default.
9298 hasRenderSpan ?: boolean ;
9399 // If component updates should be displayed as spans. True by default.
94100 hasUpdateSpan ?: boolean ;
95- // props from child component
101+ // props given to component being profiled.
96102 updateProps : { [ key : string ] : any } ;
97103} ;
98104
@@ -147,25 +153,33 @@ class Profiler extends React.Component<ProfilerProps> {
147153 }
148154 }
149155
150- public componentDidUpdate ( prevProps : ProfilerProps ) : void {
151- const { hasUpdateSpan = true } = prevProps ;
152- if ( hasUpdateSpan && this . mountSpan && prevProps . updateProps !== this . props . updateProps ) {
153- const changedProps = Object . keys ( prevProps ) . filter ( k => prevProps . updateProps [ k ] !== this . props . updateProps [ k ] ) ;
156+ public componentDidUpdate ( { updateProps, hasUpdateSpan = true } : ProfilerProps ) : void {
157+ // Only generate an update span if hasUpdateSpan is true, if there is a valid mountSpan,
158+ // and if the updateProps have changed. It is ok to not do a deep equality check here as it is expensive.
159+ // We are just trying to give baseline clues for further investigation.
160+ if ( hasUpdateSpan && this . mountSpan && updateProps !== this . props . updateProps ) {
161+ // See what props haved changed between the previous props, and the current props. This is
162+ // set as data on the span. We just store the prop keys as the values could be potenially very large.
163+ const changedProps = Object . keys ( updateProps ) . filter ( k => updateProps [ k ] !== this . props . updateProps [ k ] ) ;
154164 if ( changedProps . length > 0 ) {
165+ // The update span is a point in time span with 0 duration, just signifying that the component
166+ // has been updated.
155167 const now = timestampWithMs ( ) ;
156- const updateSpan = this . mountSpan . startChild ( {
157- description : `<${ prevProps . name } >` ,
168+ this . mountSpan . startChild ( {
169+ data : {
170+ changedProps,
171+ } ,
172+ description : `<${ this . props . name } >` ,
158173 endTimestamp : now ,
159174 op : `react.update` ,
160175 startTimestamp : now ,
161176 } ) ;
162-
163- updateSpan . setData ( 'changedProps' , changedProps ) ;
164177 }
165178 }
166179 }
167180
168- // If a component doesn't mount, the render activity will be end when the
181+ // If a component is unmounted, we can say it is no longer on the screen.
182+ // This means we can finish the span representing the component render.
169183 public componentWillUnmount ( ) : void {
170184 if ( this . renderSpan ) {
171185 this . renderSpan . finish ( ) ;
@@ -179,13 +193,16 @@ class Profiler extends React.Component<ProfilerProps> {
179193
180194/**
181195 * withProfiler is a higher order component that wraps a
182- * component in a {@link Profiler} component.
196+ * component in a {@link Profiler} component. It is recommended that
197+ * the higher order component be used over the regular {@link Profiler} component.
183198 *
184199 * @param WrappedComponent component that is wrapped by Profiler
185200 * @param options the {@link ProfilerProps} you can pass into the Profiler
186201 */
187202function withProfiler < P extends object > (
188203 WrappedComponent : React . ComponentType < P > ,
204+ // We do not want to have `updateProps` given in options, it is instead filled through
205+ // the HOC.
189206 options ?: Pick < Partial < ProfilerProps > , Exclude < keyof ProfilerProps , 'updateProps' > > ,
190207) : React . FC < P > {
191208 const componentDisplayName =
0 commit comments