[Transition Tracing] Don't call transition callbacks if no transition name specified (#24887)
This PR checks to see if `transition.name` is defined before adding the transition so we avoid doing unnecessary work for transitions without a transition name
Luna Ruan committed
Jul 11, 2022 at 18:00 UTC
e225fa43ada4f4cf3d3ba4982cdd81bb093eaa46
3 files changed
+83
-2
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+1
-1
@@ -641,7 +641,7 @@ export function scheduleUpdateOnFiber(
641
642
if (enableTransitionTracing) {
643
const transition = ReactCurrentBatchConfig.transition;
644
- if (transition !== null) {
644
+ if (transition !== null && transition.name != null) {
645
if (transition.startTime === -1) {
646
transition.startTime = now();
647
}
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+1
-1
@@ -641,7 +641,7 @@ export function scheduleUpdateOnFiber(
641
642
if (enableTransitionTracing) {
643
const transition = ReactCurrentBatchConfig.transition;
644
- if (transition !== null) {
644
+ if (transition !== null && transition.name != null) {
645
if (transition.startTime === -1) {
646
transition.startTime = now();
647
}
packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js
+81
@@ -160,6 +160,87 @@ describe('ReactInteractionTracing', () => {
160
return Promise.resolve().then(() => {});
161
}
162
163
+ // @gate enableTransitionTracing
164
+ it(' should not call callbacks when transition is not defined', async () => {
165
+ const transitionCallbacks = {
166
+ onTransitionStart: (name, startTime) => {
167
+ Scheduler.unstable_yieldValue(
168
+ `onTransitionStart(${name}, ${startTime})`,
169
+ );
170
+ },
171
+ onTransitionProgress: (name, startTime, endTime, pending) => {
172
+ const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
173
+ Scheduler.unstable_yieldValue(
174
+ `onTransitionProgress(${name}, ${startTime}, ${endTime}, [${suspenseNames}])`,
175
+ );
176
+ },
177
+ onTransitionComplete: (name, startTime, endTime) => {
178
+ Scheduler.unstable_yieldValue(
179
+ `onTransitionComplete(${name}, ${startTime}, ${endTime})`,
180
+ );
181
+ },
182
+ onMarkerProgress: (
183
+ transitioName,
184
+ markerName,
185
+ startTime,
186
+ currentTime,
187
+ pending,
188
+ ) => {
189
+ const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
190
+ Scheduler.unstable_yieldValue(
191
+ `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`,
192
+ );
193
+ },
194
+ onMarkerComplete: (transitioName, markerName, startTime, endTime) => {
195
+ Scheduler.unstable_yieldValue(
196
+ `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`,
197
+ );
198
+ },
199
+ };
200
+
201
+ function App({navigate}) {
202
+ return (
203
+ <div>
204
+ {navigate ? (
205
+ <React.unstable_TracingMarker name="marker">
206
+ <Text text="Page Two" />
207
+ </React.unstable_TracingMarker>
208
+ ) : (
209
+ <Text text="Page One" />
210
+ )}
211
+ </div>
212
+ );
213
+ }
214
+
215
+ const root = ReactNoop.createRoot({transitionCallbacks});
216
+ await act(async () => {
217
+ root.render(<App navigate={false} />);
218
+ ReactNoop.expire(1000);
219
+ await advanceTimers(1000);
220
+
221
+ expect(Scheduler).toFlushAndYield(['Page One']);
222
+
223
+ await act(async () => {
224
+ startTransition(() => root.render(<App navigate={true} />));
225
+
226
+ ReactNoop.expire(1000);
227
+ await advanceTimers(1000);
228
+
229
+ // Doesn't call transition or marker code
230
+ expect(Scheduler).toFlushAndYield(['Page Two']);
231
+
232
+ startTransition(() => root.render(<App navigate={false} />), {
233
+ name: 'transition',
234
+ });
235
+ expect(Scheduler).toFlushAndYield([
236
+ 'Page One',
237
+ 'onTransitionStart(transition, 2000)',
238
+ 'onTransitionComplete(transition, 2000, 2000)',
239
+ ]);
240
+ });
241
+ });
242
+ });
243
+
244
// @gate enableTransitionTracing
245
it('should correctly trace basic interaction', async () => {
246
const transitionCallbacks = {