1811
);
1812
});
1813
1814
+ // @gate enableLegacyCache
1815
+ it('throttles content from appearing if a fallback was filled in recently', async () => {
1816
+ function Foo() {
1817
+ Scheduler.log('Foo');
1818
+ return (
1819
+ <>
1820
+ <Suspense fallback={<Text text="Loading A..." />}>
1821
+ <AsyncText text="A" />
1822
+ </Suspense>
1823
+ <Suspense fallback={<Text text="Loading B..." />}>
1824
+ <AsyncText text="B" />
1825
+ </Suspense>
1826
+ </>
1827
+ );
1828
+ }
1829
+
1830
+ ReactNoop.render(<Foo />);
1831
+ // Start rendering
1832
+ await waitForAll([
1833
+ 'Foo',
1834
+ 'Suspend! [A]',
1835
+ 'Loading A...',
1836
+ 'Suspend! [B]',
1837
+ 'Loading B...',
1838
+ ]);
1839
+ expect(ReactNoop).toMatchRenderedOutput(
1840
+ <>
1841
+ <span prop="Loading A..." />
1842
+ <span prop="Loading B..." />
1843
+ </>,
1844
+ );
1845
+
1846
+ // Resolve only A. B will still be loading.
1847
+ await act(async () => {
1848
+ await resolveText('A');
1849
+
1850
+ // If we didn't advance the time here, A would not commit; it would
1851
+ // be throttled because the fallback would have appeared too recently.
1852
+ Scheduler.unstable_advanceTime(10000);
1853
+ jest.advanceTimersByTime(10000);
1854
+ await waitForPaint(['A']);
1855
+ expect(ReactNoop).toMatchRenderedOutput(
1856
+ <>
1857
+ <span prop="A" />
1858
+ <span prop="Loading B..." />
1859
+ </>,
1860
+ );
1861
+ });
1862
+
1863
+ // Advance by a small amount of time. For testing purposes, this is meant
1864
+ // to be just under the throttling interval. It's a heurstic, though, so
1865
+ // if we adjust the heuristic we might have to update this test, too.
1866
+ Scheduler.unstable_advanceTime(400);
1867
+ jest.advanceTimersByTime(400);
1868
+
1869
+ // Now resolve B.
1870
+ await act(async () => {
1871
+ await resolveText('B');
1872
+ await waitForPaint(['B']);
1873
+
1874
+ if (gate(flags => flags.alwaysThrottleRetries)) {
1875
+ // B should not commit yet. Even though it's been a long time since its
1876
+ // fallback was shown, it hasn't been long since A appeared. So B's
1877
+ // appearance is throttled to reduce jank.
1878
+ expect(ReactNoop).toMatchRenderedOutput(
1879
+ <>
1880
+ <span prop="A" />
1881
+ <span prop="Loading B..." />
1882
+ </>,
1883
+ );
1884
+
1885
+ // Advance time a little bit more. Now it commits because enough time
1886
+ // has passed.
1887
+ Scheduler.unstable_advanceTime(100);
1888
+ jest.advanceTimersByTime(100);
1889
+ await waitForAll([]);
1890
+ expect(ReactNoop).toMatchRenderedOutput(
1891
+ <>
1892
+ <span prop="A" />
1893
+ <span prop="B" />
1894
+ </>,
1895
+ );
1896
+ } else {
1897
+ // Old behavior, gated until this rolls out at Meta:
1898
+ //
1899
+ // B appears immediately, without being throttled.
1900
+ expect(ReactNoop).toMatchRenderedOutput(
1901
+ <>
1902
+ <span prop="A" />
1903
+ <span prop="B" />
1904
+ </>,
1905
+ );
1906
+ }
1907
+ });
1908
+ });
1909
+
1910
// TODO: flip to "warns" when this is implemented again.
1911
// @gate enableLegacyCache
1912
it('does not warn when a low priority update suspends inside a high priority update for functional components', async () => {