@samitouri / QOS-React-1 / commits / c21bcd627b

Clean up enableUnifiedSyncLane flag (#30062)

`enableUnifiedSyncLane` now passes everywhere. Let's clean it up Implemented with https://github.com/facebook/react/pull/27646 Flag enabled with https://github.com/facebook/react/pull/27646, https://github.com/facebook/react/pull/28269, https://github.com/facebook/react/pull/29052

Jack Pope committed Jun 24, 2024 at 11:18 UTC c21bcd627b6a8f31548edfc149dd3b879fea6558
20 files changed +62 -276
packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.js
+3 -12
@@ -313,21 +313,12 @@ describe('ReactDOMFiberAsync', () => {
313 assertLog([]);
314 });
315 // Only the active updates have flushed
316 - if (gate(flags => flags.enableUnifiedSyncLane)) {
317 - expect(container.textContent).toEqual('ABC');
318 - assertLog(['ABC']);
319 - } else {
320 - expect(container.textContent).toEqual('BC');
321 - assertLog(['BC']);
322 - }
316 + expect(container.textContent).toEqual('ABC');
317 + assertLog(['ABC']);
318
319 await act(() => {
320 instance.push('D');
326 - if (gate(flags => flags.enableUnifiedSyncLane)) {
327 - expect(container.textContent).toEqual('ABC');
328 - } else {
329 - expect(container.textContent).toEqual('BC');
330 - }
321 + expect(container.textContent).toEqual('ABC');
322 assertLog([]);
323 });
324 assertLog(['ABCD']);
packages/react-reconciler/src/ReactFiberLane.js
+6 -10
@@ -23,7 +23,6 @@ import {
23 enableRetryLaneExpiration,
24 enableSchedulingProfiler,
25 enableTransitionTracing,
26 - enableUnifiedSyncLane,
26 enableUpdaterTracking,
27 syncLaneExpirationMs,
28 transitionLaneExpirationMs,
@@ -51,9 +50,8 @@ export const InputContinuousLane: Lane = /* */ 0b0000000000000000000
50 export const DefaultHydrationLane: Lane = /* */ 0b0000000000000000000000000010000;
51 export const DefaultLane: Lane = /* */ 0b0000000000000000000000000100000;
52
54 -export const SyncUpdateLanes: Lane = enableUnifiedSyncLane
55 - ? SyncLane | InputContinuousLane | DefaultLane
56 - : SyncLane;
53 +export const SyncUpdateLanes: Lane =
54 + SyncLane | InputContinuousLane | DefaultLane;
55
56 const TransitionHydrationLane: Lane = /* */ 0b0000000000000000000000001000000;
57 const TransitionLanes: Lanes = /* */ 0b0000000001111111111111110000000;
@@ -151,11 +149,9 @@ let nextTransitionLane: Lane = TransitionLane1;
149 let nextRetryLane: Lane = RetryLane1;
150
151 function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
154 - if (enableUnifiedSyncLane) {
155 - const pendingSyncLanes = lanes & SyncUpdateLanes;
156 - if (pendingSyncLanes !== 0) {
157 - return pendingSyncLanes;
158 - }
152 + const pendingSyncLanes = lanes & SyncUpdateLanes;
153 + if (pendingSyncLanes !== 0) {
154 + return pendingSyncLanes;
155 }
156 switch (getHighestPriorityLane(lanes)) {
157 case SyncHydrationLane:
@@ -826,7 +822,7 @@ export function getBumpedLaneForHydration(
822 const renderLane = getHighestPriorityLane(renderLanes);
823
824 let lane;
829 - if (enableUnifiedSyncLane && (renderLane & SyncUpdateLanes) !== NoLane) {
825 + if ((renderLane & SyncUpdateLanes) !== NoLane) {
826 lane = SyncHydrationLane;
827 } else {
828 switch (renderLane) {
packages/react-reconciler/src/__tests__/Activity-test.js
+2 -7
@@ -698,15 +698,10 @@ describe('Activity', () => {
698 );
699
700 // Before the inner update can finish, we receive another pair of updates.
701 - if (gate(flags => flags.enableUnifiedSyncLane)) {
702 - React.startTransition(() => {
703 - setOuter(2);
704 - setInner(2);
705 - });
706 - } else {
701 + React.startTransition(() => {
702 setOuter(2);
703 setInner(2);
709 - }
704 + });
705
706 // Also, before either of these new updates are processed, the hidden
707 // tree is revealed at high priority.
packages/react-reconciler/src/__tests__/ReactBatching-test.internal.js
+2 -12
@@ -159,17 +159,7 @@ describe('ReactBlockingMode', () => {
159 );
160
161 // Now flush the first update
162 - if (gate(flags => flags.enableUnifiedSyncLane)) {
163 - assertLog(['A1', 'B1']);
164 - expect(root).toMatchRenderedOutput('A1B1');
165 - } else {
166 - // Only the second update should have flushed synchronously
167 - assertLog(['B1']);
168 - expect(root).toMatchRenderedOutput('A0B1');
169 -
170 - // Now flush the first update
171 - await waitForAll(['A1']);
172 - expect(root).toMatchRenderedOutput('A1B1');
173 - }
162 + assertLog(['A1', 'B1']);
163 + expect(root).toMatchRenderedOutput('A1B1');
164 });
165 });
packages/react-reconciler/src/__tests__/ReactClassSetStateCallback-test.js
+2 -6
@@ -39,13 +39,9 @@ describe('ReactClassSetStateCallback', () => {
39 assertLog([0]);
40
41 await act(() => {
42 - if (gate(flags => flags.enableUnifiedSyncLane)) {
43 - React.startTransition(() => {
44 - app.setState({step: 1}, () => Scheduler.log('Callback 1'));
45 - });
46 - } else {
42 + React.startTransition(() => {
43 app.setState({step: 1}, () => Scheduler.log('Callback 1'));
48 - }
44 + });
45 ReactNoop.flushSync(() => {
46 app.setState({step: 2}, () => Scheduler.log('Callback 2'));
47 });
packages/react-reconciler/src/__tests__/ReactFlushSync-test.js
+2 -9
@@ -102,20 +102,13 @@ describe('ReactFlushSync', () => {
102
103 // The passive effect will schedule a sync update and a normal update.
104 // They should commit in two separate batches. First the sync one.
105 - await waitForPaint(
106 - gate(flags => flags.enableUnifiedSyncLane) ? ['1, 1'] : ['1, 0'],
107 - );
105 + await waitForPaint(['1, 1']);
106
107 // The remaining update is not sync
108 ReactDOM.flushSync();
109 assertLog([]);
110
113 - if (gate(flags => flags.enableUnifiedSyncLane)) {
114 - await waitForPaint([]);
115 - } else {
116 - // Now flush it.
117 - await waitForPaint(['1, 1']);
118 - }
111 + await waitForPaint([]);
112 });
113 expect(getVisibleChildren(container)).toEqual('1, 1');
114
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+2 -7
@@ -541,13 +541,8 @@ describe('ReactHooks', () => {
541 });
542 };
543
544 - if (gate(flags => flags.enableUnifiedSyncLane)) {
545 - // Update at transition priority
546 - React.startTransition(() => update(n => n * 100));
547 - } else {
548 - // Update at normal priority
549 - ReactTestRenderer.unstable_batchedUpdates(() => update(n => n * 100));
550 - }
544 + // Update at transition priority
545 + React.startTransition(() => update(n => n * 100));
546 // The new state is eagerly computed.
547 assertLog(['Compute state (1 -> 100)']);
548
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+3 -14
@@ -899,15 +899,8 @@ describe('ReactHooksWithNoopRenderer', () => {
899 ReactNoop.flushSync(() => {
900 counter.current.dispatch(INCREMENT);
901 });
902 - if (gate(flags => flags.enableUnifiedSyncLane)) {
903 - assertLog(['Count: 4']);
904 - expect(ReactNoop).toMatchRenderedOutput(<span prop="Count: 4" />);
905 - } else {
906 - assertLog(['Count: 1']);
907 - expect(ReactNoop).toMatchRenderedOutput(<span prop="Count: 1" />);
908 - await waitForAll(['Count: 4']);
909 - expect(ReactNoop).toMatchRenderedOutput(<span prop="Count: 4" />);
910 - }
902 + assertLog(['Count: 4']);
903 + expect(ReactNoop).toMatchRenderedOutput(<span prop="Count: 4" />);
904 });
905 });
906
@@ -1613,11 +1606,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1606 // As a result we, somewhat surprisingly, commit them in the opposite order.
1607 // This should be fine because any non-discrete set of work doesn't guarantee order
1608 // and easily could've happened slightly later too.
1616 - if (gate(flags => flags.enableUnifiedSyncLane)) {
1617 - assertLog(['Will set count to 1', 'Count: 1']);
1618 - } else {
1619 - assertLog(['Will set count to 1', 'Count: 2', 'Count: 1']);
1620 - }
1609 + assertLog(['Will set count to 1', 'Count: 1']);
1610
1611 expect(ReactNoop).toMatchRenderedOutput(<span prop="Count: 1" />);
1612 });
packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js
+29 -160
@@ -156,23 +156,11 @@ describe('ReactIncrementalUpdates', () => {
156 }
157
158 // Schedule some async updates
159 - if (
160 - gate(
161 - flags =>
162 - !flags.forceConcurrentByDefaultForTesting ||
163 - flags.enableUnifiedSyncLane,
164 - )
165 - ) {
166 - React.startTransition(() => {
167 - instance.setState(createUpdate('a'));
168 - instance.setState(createUpdate('b'));
169 - instance.setState(createUpdate('c'));
170 - });
171 - } else {
159 + React.startTransition(() => {
160 instance.setState(createUpdate('a'));
161 instance.setState(createUpdate('b'));
162 instance.setState(createUpdate('c'));
175 - }
163 + });
164
165 // Begin the updates but don't flush them yet
166 await waitFor(['a', 'b', 'c']);
@@ -189,58 +177,22 @@ describe('ReactIncrementalUpdates', () => {
177 });
178
179 // The sync updates should have flushed, but not the async ones.
192 - if (
193 - gate(
194 - flags =>
195 - !flags.forceConcurrentByDefaultForTesting &&
196 - flags.enableUnifiedSyncLane,
197 - )
198 - ) {
199 - assertLog(['d', 'e', 'f']);
200 - expect(ReactNoop).toMatchRenderedOutput(<span prop="def" />);
201 - } else {
202 - // Update d was dropped and replaced by e.
203 - assertLog(['e', 'f']);
204 - expect(ReactNoop).toMatchRenderedOutput(<span prop="ef" />);
205 - }
180 + assertLog(['d', 'e', 'f']);
181 + expect(ReactNoop).toMatchRenderedOutput(<span prop="def" />);
182
183 // Now flush the remaining work. Even though e and f were already processed,
184 // they should be processed again, to ensure that the terminal state
185 // is deterministic.
210 - if (
211 - gate(
212 - flags =>
213 - !flags.forceConcurrentByDefaultForTesting &&
214 - !flags.enableUnifiedSyncLane,
215 - )
216 - ) {
217 - await waitForAll([
218 - // Since 'g' is in a transition, we'll process 'd' separately first.
219 - // That causes us to process 'd' with 'e' and 'f' rebased.
220 - 'd',
221 - 'e',
222 - 'f',
223 - // Then we'll re-process everything for 'g'.
224 - 'a',
225 - 'b',
226 - 'c',
227 - 'd',
228 - 'e',
229 - 'f',
230 - 'g',
231 - ]);
232 - } else {
233 - await waitForAll([
234 - // Then we'll re-process everything for 'g'.
235 - 'a',
236 - 'b',
237 - 'c',
238 - 'd',
239 - 'e',
240 - 'f',
241 - 'g',
242 - ]);
243 - }
186 + await waitForAll([
187 + // Then we'll re-process everything for 'g'.
188 + 'a',
189 + 'b',
190 + 'c',
191 + 'd',
192 + 'e',
193 + 'f',
194 + 'g',
195 + ]);
196 expect(ReactNoop).toMatchRenderedOutput(<span prop="abcdefg" />);
197 });
198
@@ -267,23 +219,11 @@ describe('ReactIncrementalUpdates', () => {
219 }
220
221 // Schedule some async updates
270 - if (
271 - gate(
272 - flags =>
273 - !flags.forceConcurrentByDefaultForTesting ||
274 - flags.enableUnifiedSyncLane,
275 - )
276 - ) {
277 - React.startTransition(() => {
278 - instance.setState(createUpdate('a'));
279 - instance.setState(createUpdate('b'));
280 - instance.setState(createUpdate('c'));
281 - });
282 - } else {
222 + React.startTransition(() => {
223 instance.setState(createUpdate('a'));
224 instance.setState(createUpdate('b'));
225 instance.setState(createUpdate('c'));
286 - }
226 + });
227
228 // Begin the updates but don't flush them yet
229 await waitFor(['a', 'b', 'c']);
@@ -303,57 +243,22 @@ describe('ReactIncrementalUpdates', () => {
243 });
244
245 // The sync updates should have flushed, but not the async ones.
306 - if (
307 - gate(
308 - flags =>
309 - !flags.forceConcurrentByDefaultForTesting &&
310 - flags.enableUnifiedSyncLane,
311 - )
312 - ) {
313 - assertLog(['d', 'e', 'f']);
314 - } else {
315 - // Update d was dropped and replaced by e.
316 - assertLog(['e', 'f']);
317 - }
246 + assertLog(['d', 'e', 'f']);
247 expect(ReactNoop).toMatchRenderedOutput(<span prop="f" />);
248
249 // Now flush the remaining work. Even though e and f were already processed,
250 // they should be processed again, to ensure that the terminal state
251 // is deterministic.
323 - if (
324 - gate(
325 - flags =>
326 - !flags.forceConcurrentByDefaultForTesting &&
327 - !flags.enableUnifiedSyncLane,
328 - )
329 - ) {
330 - await waitForAll([
331 - // Since 'g' is in a transition, we'll process 'd' separately first.
332 - // That causes us to process 'd' with 'e' and 'f' rebased.
333 - 'd',
334 - 'e',
335 - 'f',
336 - // Then we'll re-process everything for 'g'.
337 - 'a',
338 - 'b',
339 - 'c',
340 - 'd',
341 - 'e',
342 - 'f',
343 - 'g',
344 - ]);
345 - } else {
346 - await waitForAll([
347 - // Then we'll re-process everything for 'g'.
348 - 'a',
349 - 'b',
350 - 'c',
351 - 'd',
352 - 'e',
353 - 'f',
354 - 'g',
355 - ]);
356 - }
252 + await waitForAll([
253 + // Then we'll re-process everything for 'g'.
254 + 'a',
255 + 'b',
256 + 'c',
257 + 'd',
258 + 'e',
259 + 'f',
260 + 'g',
261 + ]);
262 expect(ReactNoop).toMatchRenderedOutput(<span prop="fg" />);
263 });
264
@@ -684,25 +589,7 @@ describe('ReactIncrementalUpdates', () => {
589 pushToLog('B'),
590 );
591 });
687 - if (gate(flags => flags.enableUnifiedSyncLane)) {
688 - assertLog(['Committed: B', 'Committed: BCD', 'Committed: ABCD']);
689 - } else {
690 - assertLog([
691 - // A and B are pending. B is higher priority, so we'll render that first.
692 - 'Committed: B',
693 - // Because A comes first in the queue, we're now in rebase mode. B must
694 - // be rebased on top of A. Also, in a layout effect, we received two new
695 - // updates: C and D. C is user-blocking and D is synchronous.
696 - //
697 - // First render the synchronous update. What we're testing here is that
698 - // B *is not dropped* even though it has lower than sync priority. That's
699 - // because we already committed it. However, this render should not
700 - // include C, because that update wasn't already committed.
701 - 'Committed: BD',
702 - 'Committed: BCD',
703 - 'Committed: ABCD',
704 - ]);
705 - }
592 + assertLog(['Committed: B', 'Committed: BCD', 'Committed: ABCD']);
593 expect(root).toMatchRenderedOutput('ABCD');
594 });
595
@@ -744,25 +631,7 @@ describe('ReactIncrementalUpdates', () => {
631 pushToLog('B'),
632 );
633 });
747 - if (gate(flags => flags.enableUnifiedSyncLane)) {
748 - assertLog(['Committed: B', 'Committed: BCD', 'Committed: ABCD']);
749 - } else {
750 - assertLog([
751 - // A and B are pending. B is higher priority, so we'll render that first.
752 - 'Committed: B',
753 - // Because A comes first in the queue, we're now in rebase mode. B must
754 - // be rebased on top of A. Also, in a layout effect, we received two new
755 - // updates: C and D. C is user-blocking and D is synchronous.
756 - //
757 - // First render the synchronous update. What we're testing here is that
758 - // B *is not dropped* even though it has lower than sync priority. That's
759 - // because we already committed it. However, this render should not
760 - // include C, because that update wasn't already committed.
761 - 'Committed: BD',
762 - 'Committed: BCD',
763 - 'Committed: ABCD',
764 - ]);
765 - }
634 + assertLog(['Committed: B', 'Committed: BCD', 'Committed: ABCD']);
635 expect(root).toMatchRenderedOutput('ABCD');
636 });
637
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+1 -3
@@ -3506,7 +3506,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3506 });
3507
3508 // @gate enableLegacyCache
3509 - // @gate forceConcurrentByDefaultForTesting
3509 it('regression: ping at high priority causes update to be dropped', async () => {
3510 const {useState, useTransition} = React;
3511
@@ -3573,10 +3572,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3572 });
3573
3574 await waitFor([
3576 - 'B',
3575 'Suspend! [A1]',
3576 'Loading...',
3579 -
3577 + 'B',
3578 'Suspend! [A2]',
3579 'Loading...',
3580 'Suspend! [B2]',
packages/react-reconciler/src/__tests__/ReactTransition-test.js
+8 -21
@@ -925,28 +925,15 @@ describe('ReactTransition', () => {
925 updateNormalPri();
926 });
927
928 - if (gate(flags => flags.enableUnifiedSyncLane)) {
929 - assertLog([
930 - 'Normal pri: 0',
931 - 'Commit',
932 -
933 - // Normal pri update.
934 - 'Transition pri: 1',
935 - 'Normal pri: 1',
936 - 'Commit',
937 - ]);
938 - } else {
939 - assertLog([
940 - // Finish transition update.
941 - 'Normal pri: 0',
942 - 'Commit',
928 + assertLog([
929 + 'Normal pri: 0',
930 + 'Commit',
931
944 - // Normal pri update.
945 - 'Transition pri: 1',
946 - 'Normal pri: 1',
947 - 'Commit',
948 - ]);
949 - }
932 + // Normal pri update.
933 + 'Transition pri: 1',
934 + 'Normal pri: 1',
935 + 'Commit',
936 + ]);
937
938 expect(root).toMatchRenderedOutput('Transition pri: 1, Normal pri: 1');
939 });
packages/shared/ReactFeatureFlags.js
-2
@@ -210,8 +210,6 @@ export const enableUseDeferredValueInitialArg = true;
210 // Enables time slicing for updates that aren't wrapped in startTransition.
211 export const forceConcurrentByDefaultForTesting = false;
212
213 -export const enableUnifiedSyncLane = true;
214 -
213 // Adds an opt-in to time slicing for updates that aren't wrapped in startTransition.
214 export const allowConcurrentByDefault = false;
215
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -79,7 +79,6 @@ export const enableSuspenseCallback = false;
79 export const enableTaint = true;
80 export const enableTransitionTracing = false;
81 export const enableTrustedTypesIntegration = false;
82 -export const enableUnifiedSyncLane = true;
82 export const enableUpdaterTracking = __PROFILE__;
83 export const enableUseDeferredValueInitialArg = true;
84 export const enableUseEffectEventHook = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -71,7 +71,6 @@ export const enableSuspenseCallback = false;
71 export const enableTaint = true;
72 export const enableTransitionTracing = false;
73 export const enableTrustedTypesIntegration = false;
74 -export const enableUnifiedSyncLane = true;
74 export const enableUseDeferredValueInitialArg = true;
75 export const enableUseEffectEventHook = false;
76 export const enableUseMemoCacheHook = true;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -54,7 +54,6 @@ export const disableSchedulerTimeoutInWorkLoop = false;
54 export const enableLazyContextPropagation = false;
55 export const enableLegacyHidden = false;
56 export const forceConcurrentByDefaultForTesting = false;
57 -export const enableUnifiedSyncLane = __EXPERIMENTAL__;
57 export const allowConcurrentByDefault = false;
58
59 export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
-1
@@ -66,7 +66,6 @@ export const enableSuspenseCallback = false;
66 export const enableTaint = true;
67 export const enableTransitionTracing = false;
68 export const enableTrustedTypesIntegration = false;
69 -export const enableUnifiedSyncLane = true;
69 export const enableUpdaterTracking = false;
70 export const enableUseDeferredValueInitialArg = __EXPERIMENTAL__;
71 export const enableUseEffectEventHook = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -56,7 +56,6 @@ export const disableSchedulerTimeoutInWorkLoop = false;
56 export const enableLazyContextPropagation = false;
57 export const enableLegacyHidden = false;
58 export const forceConcurrentByDefaultForTesting = false;
59 -export const enableUnifiedSyncLane = true;
59 export const allowConcurrentByDefault = true;
60
61 export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -16,7 +16,6 @@
16 export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
17 export const enableLazyContextPropagation = __VARIANT__;
18 export const forceConcurrentByDefaultForTesting = __VARIANT__;
19 -export const enableUnifiedSyncLane = __VARIANT__;
19 export const enableTransitionTracing = __VARIANT__;
20 export const enableDeferRootSchedulingToMicrotask = __VARIANT__;
21 export const alwaysThrottleRetries = true;
packages/shared/forks/ReactFeatureFlags.www.js
-1
@@ -18,7 +18,6 @@ export const {
18 enableTrustedTypesIntegration,
19 enableDebugTracing,
20 enableLazyContextPropagation,
21 - enableUnifiedSyncLane,
21 enableRetryLaneExpiration,
22 enableTransitionTracing,
23 enableDeferRootSchedulingToMicrotask,
packages/use-subscription/src/__tests__/useSubscription-test.js
+2 -6
@@ -434,13 +434,9 @@ describe('useSubscription', () => {
434 observableA.next('a-2');
435
436 // Update again
437 - if (gate(flags => flags.enableUnifiedSyncLane)) {
438 - React.startTransition(() => {
439 - root.render(<Parent observed={observableA} />);
440 - });
441 - } else {
437 + React.startTransition(() => {
438 root.render(<Parent observed={observableA} />);
443 - }
439 + });
440
441 // Flush everything and ensure that the correct subscribable is used
442 await waitForAll([