Skip to content

Commit 9bb7288

Browse files
committed
Gate rel="expect" behind enableFizzBlockingRender
1 parent 21fdf30 commit 9bb7288

19 files changed

+194
-55
lines changed

packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {Children} from 'react';
3434
import {
3535
enableFizzExternalRuntime,
3636
enableSrcObject,
37+
enableFizzBlockingRender,
3738
} from 'shared/ReactFeatureFlags';
3839

3940
import type {
@@ -4146,16 +4147,21 @@ export function writeCompletedRoot(
41464147
// we need to track the paint time of the shell so we know how much to throttle the reveal.
41474148
writeShellTimeInstruction(destination, resumableState, renderState);
41484149
}
4149-
const preamble = renderState.preamble;
4150-
if (preamble.htmlChunks || preamble.headChunks) {
4151-
// If we rendered the whole document, then we emitted a rel="expect" that needs a
4152-
// matching target. Normally we use one of the bootstrap scripts for this but if
4153-
// there are none, then we need to emit a tag to complete the shell.
4154-
if ((resumableState.instructions & SentCompletedShellId) === NothingSent) {
4155-
writeChunk(destination, startChunkForTag('template'));
4156-
writeCompletedShellIdAttribute(destination, resumableState);
4157-
writeChunk(destination, endOfStartTag);
4158-
writeChunk(destination, endChunkForTag('template'));
4150+
if (enableFizzBlockingRender) {
4151+
const preamble = renderState.preamble;
4152+
if (preamble.htmlChunks || preamble.headChunks) {
4153+
// If we rendered the whole document, then we emitted a rel="expect" that needs a
4154+
// matching target. Normally we use one of the bootstrap scripts for this but if
4155+
// there are none, then we need to emit a tag to complete the shell.
4156+
if (
4157+
(resumableState.instructions & SentCompletedShellId) ===
4158+
NothingSent
4159+
) {
4160+
writeChunk(destination, startChunkForTag('template'));
4161+
writeCompletedShellIdAttribute(destination, resumableState);
4162+
writeChunk(destination, endOfStartTag);
4163+
writeChunk(destination, endChunkForTag('template'));
4164+
}
41594165
}
41604166
}
41614167
return writeBootstrap(destination, renderState);
@@ -5040,11 +5046,13 @@ function writeBlockingRenderInstruction(
50405046
resumableState: ResumableState,
50415047
renderState: RenderState,
50425048
): void {
5043-
const idPrefix = resumableState.idPrefix;
5044-
const shellId = '\u00AB' + idPrefix + 'R\u00BB';
5045-
writeChunk(destination, blockingRenderChunkStart);
5046-
writeChunk(destination, stringToChunk(escapeTextForBrowser(shellId)));
5047-
writeChunk(destination, blockingRenderChunkEnd);
5049+
if (enableFizzBlockingRender) {
5050+
const idPrefix = resumableState.idPrefix;
5051+
const shellId = '\u00AB' + idPrefix + 'R\u00BB';
5052+
writeChunk(destination, blockingRenderChunkStart);
5053+
writeChunk(destination, stringToChunk(escapeTextForBrowser(shellId)));
5054+
writeChunk(destination, blockingRenderChunkEnd);
5055+
}
50485056
}
50495057

50505058
const completedShellIdAttributeStart = stringToPrecomputedChunk(' id="');

packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3590,7 +3590,9 @@ describe('ReactDOMFizzServer', () => {
35903590
(gate(flags => flags.shouldUseFizzExternalRuntime)
35913591
? '<script src="react-dom-bindings/src/server/ReactDOMServerExternalRuntime.js" async=""></script>'
35923592
: '') +
3593-
'<link rel="expect" href="#«R»" blocking="render">',
3593+
(gate(flags => flags.enableFizzBlockingRender)
3594+
? '<link rel="expect" href="#«R»" blocking="render">'
3595+
: ''),
35943596
);
35953597
});
35963598

@@ -4523,7 +4525,15 @@ describe('ReactDOMFizzServer', () => {
45234525

45244526
// the html should be as-is
45254527
expect(document.documentElement.innerHTML).toEqual(
4526-
'<head><script src="react-dom-bindings/src/server/ReactDOMServerExternalRuntime.js" async=""></script><link rel="expect" href="#«R»" blocking="render"></head><body><p>hello world!</p><template id="«R»"></template></body>',
4528+
'<head><script src="react-dom-bindings/src/server/ReactDOMServerExternalRuntime.js" async=""></script>' +
4529+
(gate(flags => flags.enableFizzBlockingRender)
4530+
? '<link rel="expect" href="#«R»" blocking="render">'
4531+
: '') +
4532+
'</head><body><p>hello world!</p>' +
4533+
(gate(flags => flags.enableFizzBlockingRender)
4534+
? '<template id="«R»"></template>'
4535+
: '') +
4536+
'</body>',
45274537
);
45284538
});
45294539

@@ -6512,7 +6522,14 @@ describe('ReactDOMFizzServer', () => {
65126522
(gate(flags => flags.shouldUseFizzExternalRuntime)
65136523
? '<script src="react-dom-bindings/src/server/ReactDOMServerExternalRuntime.js" async=""></script>'
65146524
: '') +
6515-
'<link rel="expect" href="#«R»" blocking="render"></head><body><script>try { foo() } catch (e) {} ;</script><template id="«R»"></template></body></html>',
6525+
(gate(flags => flags.enableFizzBlockingRender)
6526+
? '<link rel="expect" href="#«R»" blocking="render">'
6527+
: '') +
6528+
'</head><body><script>try { foo() } catch (e) {} ;</script>' +
6529+
(gate(flags => flags.enableFizzBlockingRender)
6530+
? '<template id="«R»"></template>'
6531+
: '') +
6532+
'</body></html>',
65166533
);
65176534
});
65186535

packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,15 @@ describe('ReactDOMFizzServerBrowser', () => {
8484
),
8585
);
8686
const result = await readResult(stream);
87-
expect(result).toMatchInlineSnapshot(
88-
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
89-
);
87+
if (gate(flags => flags.enableFizzBlockingRender)) {
88+
expect(result).toMatchInlineSnapshot(
89+
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
90+
);
91+
} else {
92+
expect(result).toMatchInlineSnapshot(
93+
`"<!DOCTYPE html><html><head></head><body>hello world</body></html>"`,
94+
);
95+
}
9096
});
9197

9298
it('should emit bootstrap script src at the end', async () => {
@@ -529,7 +535,15 @@ describe('ReactDOMFizzServerBrowser', () => {
529535

530536
const result = await readResult(stream);
531537
expect(result).toEqual(
532-
'<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/><title>foo</title></head><body>bar<template id="«R»"></template></body></html>',
538+
'<!DOCTYPE html><html><head>' +
539+
(gate(flags => flags.enableFizzBlockingRender)
540+
? '<link rel="expect" href="#«R»" blocking="render"/>'
541+
: '') +
542+
'<title>foo</title></head><body>bar' +
543+
(gate(flags => flags.enableFizzBlockingRender)
544+
? '<template id="«R»"></template>'
545+
: '') +
546+
'</body></html>',
533547
);
534548
});
535549

packages/react-dom/src/__tests__/ReactDOMFizzServerEdge-test.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,14 @@ describe('ReactDOMFizzServerEdge', () => {
7171
setTimeout(resolve, 1);
7272
});
7373

74-
expect(result).toMatchInlineSnapshot(
75-
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body><main>hello</main><template id="«R»"></template></body></html>"`,
76-
);
74+
if (gate(flags => flags.enableFizzBlockingRender)) {
75+
expect(result).toMatchInlineSnapshot(
76+
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body><main>hello</main><template id="«R»"></template></body></html>"`,
77+
);
78+
} else {
79+
expect(result).toMatchInlineSnapshot(
80+
`"<!DOCTYPE html><html><head></head><body><main>hello</main></body></html>"`,
81+
);
82+
}
7783
});
7884
});

packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,15 @@ describe('ReactDOMFizzServerNode', () => {
7878
pipe(writable);
7979
});
8080
// with Float, we emit empty heads if they are elided when rendering <html>
81-
expect(output.result).toMatchInlineSnapshot(
82-
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
83-
);
81+
if (gate(flags => flags.enableFizzBlockingRender)) {
82+
expect(output.result).toMatchInlineSnapshot(
83+
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
84+
);
85+
} else {
86+
expect(output.result).toMatchInlineSnapshot(
87+
`"<!DOCTYPE html><html><head></head><body>hello world</body></html>"`,
88+
);
89+
}
8490
});
8591

8692
it('should emit bootstrap script src at the end', async () => {

packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,15 @@ describe('ReactDOMFizzStaticBrowser', () => {
195195
),
196196
);
197197
const prelude = await readContent(result.prelude);
198-
expect(prelude).toMatchInlineSnapshot(
199-
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
200-
);
198+
if (gate(flags => flags.enableFizzBlockingRender)) {
199+
expect(prelude).toMatchInlineSnapshot(
200+
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
201+
);
202+
} else {
203+
expect(prelude).toMatchInlineSnapshot(
204+
`"<!DOCTYPE html><html><head></head><body>hello world</body></html>"`,
205+
);
206+
}
201207
});
202208

203209
it('should emit bootstrap script src at the end', async () => {
@@ -1438,8 +1444,15 @@ describe('ReactDOMFizzStaticBrowser', () => {
14381444
expect(await readContent(content)).toBe(
14391445
'<!DOCTYPE html><html lang="en"><head>' +
14401446
'<link rel="stylesheet" href="my-style" data-precedence="high"/>' +
1441-
'<link rel="expect" href="#«R»" blocking="render"/></head>' +
1442-
'<body>Hello<template id="«R»"></template></body></html>',
1447+
(gate(flags => flags.enableFizzBlockingRender)
1448+
? '<link rel="expect" href="#«R»" blocking="render"/>'
1449+
: '') +
1450+
'</head>' +
1451+
'<body>Hello' +
1452+
(gate(flags => flags.enableFizzBlockingRender)
1453+
? '<template id="«R»"></template>'
1454+
: '') +
1455+
'</body></html>',
14431456
);
14441457
});
14451458

packages/react-dom/src/__tests__/ReactDOMFizzStaticNode-test.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,15 @@ describe('ReactDOMFizzStaticNode', () => {
6363
</html>,
6464
);
6565
const prelude = await readContent(result.prelude);
66-
expect(prelude).toMatchInlineSnapshot(
67-
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
68-
);
66+
if (gate(flags => flags.enableFizzBlockingRender)) {
67+
expect(prelude).toMatchInlineSnapshot(
68+
`"<!DOCTYPE html><html><head><link rel="expect" href="#«R»" blocking="render"/></head><body>hello world<template id="«R»"></template></body></html>"`,
69+
);
70+
} else {
71+
expect(prelude).toMatchInlineSnapshot(
72+
`"<!DOCTYPE html><html><head></head><body>hello world</body></html>"`,
73+
);
74+
}
6975
});
7076

7177
// @gate experimental

packages/react-dom/src/__tests__/ReactDOMFloat-test.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,14 @@ describe('ReactDOMFloat', () => {
704704
(gate(flags => flags.shouldUseFizzExternalRuntime)
705705
? '<script src="react-dom/unstable_server-external-runtime" async=""></script>'
706706
: '') +
707-
'<link rel="expect" href="#«R»" blocking="render"/><title>foo</title></head>' +
708-
'<body>bar<template id="«R»"></template>',
707+
(gate(flags => flags.enableFizzBlockingRender)
708+
? '<link rel="expect" href="#«R»" blocking="render"/>'
709+
: '') +
710+
'<title>foo</title></head>' +
711+
'<body>bar' +
712+
(gate(flags => flags.enableFizzBlockingRender)
713+
? '<template id="«R»"></template>'
714+
: ''),
709715
'</body></html>',
710716
]);
711717
});

packages/react-dom/src/__tests__/ReactDOMLegacyFloat-test.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,15 @@ describe('ReactDOMFloat', () => {
3434
);
3535

3636
expect(result).toEqual(
37-
'<html><head><meta charSet="utf-8"/><link rel="expect" href="#«R»" blocking="render"/>' +
38-
'<title>title</title><script src="foo"></script></head><template id="«R»"></template></html>',
37+
'<html><head><meta charSet="utf-8"/>' +
38+
(gate(flags => flags.enableFizzBlockingRender)
39+
? '<link rel="expect" href="#«R»" blocking="render"/>'
40+
: '') +
41+
'<title>title</title><script src="foo"></script></head>' +
42+
(gate(flags => flags.enableFizzBlockingRender)
43+
? '<template id="«R»"></template>'
44+
: '') +
45+
'</html>',
3946
);
4047
});
4148
});

packages/react-dom/src/__tests__/ReactRenderDocument-test.js

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,20 @@ describe('rendering React components at document', () => {
7878
root = ReactDOMClient.hydrateRoot(testDocument, <Root hello="world" />);
7979
});
8080
expect(testDocument.body.innerHTML).toBe(
81-
'Hello world' + '<template id="«R»"></template>',
81+
'Hello world' +
82+
(gate(flags => flags.enableFizzBlockingRender)
83+
? '<template id="«R»"></template>'
84+
: ''),
8285
);
8386

8487
await act(() => {
8588
root.render(<Root hello="moon" />);
8689
});
8790
expect(testDocument.body.innerHTML).toBe(
88-
'Hello moon' + '<template id="«R»"></template>',
91+
'Hello moon' +
92+
(gate(flags => flags.enableFizzBlockingRender)
93+
? '<template id="«R»"></template>'
94+
: ''),
8995
);
9096

9197
expect(body === testDocument.body).toBe(true);
@@ -112,7 +118,10 @@ describe('rendering React components at document', () => {
112118
root = ReactDOMClient.hydrateRoot(testDocument, <Root />);
113119
});
114120
expect(testDocument.body.innerHTML).toBe(
115-
'Hello world' + '<template id="«R»"></template>',
121+
'Hello world' +
122+
(gate(flags => flags.enableFizzBlockingRender)
123+
? '<template id="«R»"></template>'
124+
: ''),
116125
);
117126

118127
const originalDocEl = testDocument.documentElement;
@@ -124,9 +133,15 @@ describe('rendering React components at document', () => {
124133
expect(testDocument.firstChild).toBe(originalDocEl);
125134
expect(testDocument.head).toBe(originalHead);
126135
expect(testDocument.body).toBe(originalBody);
127-
expect(originalBody.innerHTML).toBe('<template id="«R»"></template>');
136+
expect(originalBody.innerHTML).toBe(
137+
gate(flags => flags.enableFizzBlockingRender)
138+
? '<template id="«R»"></template>'
139+
: '',
140+
);
128141
expect(originalHead.innerHTML).toBe(
129-
'<link rel="expect" href="#«R»" blocking="render">',
142+
gate(flags => flags.enableFizzBlockingRender)
143+
? '<link rel="expect" href="#«R»" blocking="render">'
144+
: '',
130145
);
131146
});
132147

@@ -166,15 +181,20 @@ describe('rendering React components at document', () => {
166181
});
167182

168183
expect(testDocument.body.innerHTML).toBe(
169-
'Hello world' + '<template id="«R»"></template>',
184+
'Hello world' +
185+
(gate(flags => flags.enableFizzBlockingRender)
186+
? '<template id="«R»"></template>'
187+
: ''),
170188
);
171189

172190
await act(() => {
173191
root.render(<Component2 />);
174192
});
175193

176194
expect(testDocument.body.innerHTML).toBe(
177-
'<template id="«R»"></template>' + 'Goodbye world',
195+
(gate(flags => flags.enableFizzBlockingRender)
196+
? '<template id="«R»"></template>'
197+
: '') + 'Goodbye world',
178198
);
179199
});
180200

@@ -205,7 +225,10 @@ describe('rendering React components at document', () => {
205225
});
206226

207227
expect(testDocument.body.innerHTML).toBe(
208-
'Hello world' + '<template id="«R»"></template>',
228+
'Hello world' +
229+
(gate(flags => flags.enableFizzBlockingRender)
230+
? '<template id="«R»"></template>'
231+
: ''),
209232
);
210233
});
211234

@@ -341,7 +364,10 @@ describe('rendering React components at document', () => {
341364
expect(testDocument.body.innerHTML).toBe(
342365
favorSafetyOverHydrationPerf
343366
? 'Hello world'
344-
: 'Goodbye world<template id="«R»"></template>',
367+
: 'Goodbye world' +
368+
(gate(flags => flags.enableFizzBlockingRender)
369+
? '<template id="«R»"></template>'
370+
: ''),
345371
);
346372
});
347373

0 commit comments

Comments
 (0)