Skip to content

Commit

Permalink
bootstrap scripts should preload with low priority. This allows the b…
Browse files Browse the repository at this point in the history
…rowser to prefer loading paint blocking resources like images even if they arrive after the script preload has been processed
  • Loading branch information
gnoff committed Aug 7, 2023
1 parent ea17cc1 commit 8928b5e
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 24 deletions.
13 changes: 11 additions & 2 deletions packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -4245,6 +4245,8 @@ export function writePreamble(
// Flush unblocked stylesheets by precedence
resources.precedences.forEach(flushAllStylesInPreamble, destination);

resources.bootstrapScripts.forEach(flushResourceInPreamble, destination);

resources.scripts.forEach(flushResourceInPreamble, destination);
resources.scripts.clear();

Expand Down Expand Up @@ -4322,6 +4324,9 @@ export function writeHoistables(
// but we want to kick off preloading as soon as possible
resources.precedences.forEach(preloadLateStyles, destination);

// bootstrap scripts should flush above script priority but these can only flush in the preamble
// so we elide the code here for performance

resources.scripts.forEach(flushResourceLate, destination);
resources.scripts.clear();

Expand Down Expand Up @@ -4875,6 +4880,7 @@ export type Resources = {
// usedImagePreloads: Set<PreloadResource>,
precedences: Map<string, Set<StyleResource>>,
stylePrecedences: Map<string, StyleTagResource>,
bootstrapScripts: Set<PreloadResource>,
scripts: Set<ScriptResource>,
explicitStylesheetPreloads: Set<PreloadResource>,
// explicitImagePreloads: Set<PreloadResource>,
Expand All @@ -4901,6 +4907,7 @@ export function createResources(): Resources {
// usedImagePreloads: new Set(),
precedences: new Map(),
stylePrecedences: new Map(),
bootstrapScripts: new Set(),
scripts: new Set(),
explicitStylesheetPreloads: new Set(),
// explicitImagePreloads: new Set(),
Expand Down Expand Up @@ -5470,6 +5477,7 @@ function preloadBootstrapScript(
rel: 'preload',
href: src,
as: 'script',
fetchPriority: 'low',
nonce,
integrity,
crossOrigin,
Expand All @@ -5481,7 +5489,7 @@ function preloadBootstrapScript(
props,
};
resources.preloadsMap.set(key, resource);
resources.explicitScriptPreloads.add(resource);
resources.bootstrapScripts.add(resource);
pushLinkImpl(resource.chunks, props);
}

Expand Down Expand Up @@ -5511,6 +5519,7 @@ function preloadBootstrapModule(
const props: PreloadModuleProps = {
rel: 'modulepreload',
href: src,
fetchPriority: 'low',
nonce,
integrity,
crossOrigin,
Expand All @@ -5522,7 +5531,7 @@ function preloadBootstrapModule(
props,
};
resources.preloadsMap.set(key, resource);
resources.explicitScriptPreloads.add(resource);
resources.bootstrapScripts.add(resource);
pushLinkImpl(resource.chunks, props);
return;
}
Expand Down
82 changes: 66 additions & 16 deletions packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -610,17 +610,30 @@ describe('ReactDOMFizzServer', () => {
});

expect(getVisibleChildren(container)).toEqual([
<link rel="preload" href="init.js" as="script" nonce={CSPnonce} />,
<link
rel="preload"
fetchpriority="low"
href="init.js"
as="script"
nonce={CSPnonce}
/>,
<link
rel="preload"
fetchpriority="low"
href="init2.js"
as="script"
nonce={CSPnonce}
integrity="init2hash"
/>,
<link rel="modulepreload" href="init.mjs" nonce={CSPnonce} />,
<link
rel="modulepreload"
fetchpriority="low"
href="init.mjs"
nonce={CSPnonce}
/>,
<link
rel="modulepreload"
fetchpriority="low"
href="init2.mjs"
nonce={CSPnonce}
integrity="init2hash"
Expand All @@ -640,17 +653,30 @@ describe('ReactDOMFizzServer', () => {
resolve({default: Text});
});
expect(getVisibleChildren(container)).toEqual([
<link rel="preload" href="init.js" as="script" nonce={CSPnonce} />,
<link
rel="preload"
fetchpriority="low"
href="init.js"
as="script"
nonce={CSPnonce}
/>,
<link
rel="preload"
fetchpriority="low"
href="init2.js"
as="script"
nonce={CSPnonce}
integrity="init2hash"
/>,
<link rel="modulepreload" href="init.mjs" nonce={CSPnonce} />,
<link
rel="modulepreload"
fetchpriority="low"
href="init.mjs"
nonce={CSPnonce}
/>,
<link
rel="modulepreload"
fetchpriority="low"
href="init2.mjs"
nonce={CSPnonce}
integrity="init2hash"
Expand Down Expand Up @@ -3797,12 +3823,23 @@ describe('ReactDOMFizzServer', () => {
expect(getVisibleChildren(document)).toEqual(
<html>
<head>
<link rel="preload" href="foo" as="script" />
<link rel="preload" href="bar" as="script" />
<link rel="preload" href="baz" as="script" integrity="qux" />
<link rel="modulepreload" href="quux" />
<link rel="modulepreload" href="corge" />
<link rel="modulepreload" href="grault" integrity="garply" />
<link rel="preload" fetchpriority="low" href="foo" as="script" />
<link rel="preload" fetchpriority="low" href="bar" as="script" />
<link
rel="preload"
fetchpriority="low"
href="baz"
as="script"
integrity="qux"
/>
<link rel="modulepreload" fetchpriority="low" href="quux" />
<link rel="modulepreload" fetchpriority="low" href="corge" />
<link
rel="modulepreload"
fetchpriority="low"
href="grault"
integrity="garply"
/>
</head>
<body>
<div>hello world</div>
Expand Down Expand Up @@ -3866,14 +3903,27 @@ describe('ReactDOMFizzServer', () => {
expect(getVisibleChildren(document)).toEqual(
<html>
<head>
<link rel="preload" href="foo" as="script" />
<link rel="preload" href="bar" as="script" />
<link rel="preload" href="baz" as="script" crossorigin="" />
<link rel="preload" href="qux" as="script" crossorigin="" />
<link rel="modulepreload" href="quux" />
<link rel="modulepreload" href="corge" />
<link rel="preload" fetchpriority="low" href="foo" as="script" />
<link rel="preload" fetchpriority="low" href="bar" as="script" />
<link
rel="preload"
fetchpriority="low"
href="baz"
as="script"
crossorigin=""
/>
<link
rel="preload"
fetchpriority="low"
href="qux"
as="script"
crossorigin=""
/>
<link rel="modulepreload" fetchpriority="low" href="quux" />
<link rel="modulepreload" fetchpriority="low" href="corge" />
<link
rel="modulepreload"
fetchpriority="low"
href="grault"
crossorigin="use-credentials"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('ReactDOMFizzServerBrowser', () => {
);
const result = await readResult(stream);
expect(result).toMatchInlineSnapshot(
`"<link rel="preload" href="init.js" as="script"/><link rel="modulepreload" href="init.mjs"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
`"<link rel="preload" href="init.js" as="script" fetchPriority="low"/><link rel="modulepreload" href="init.mjs" fetchPriority="low"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
);
});

Expand Down Expand Up @@ -500,7 +500,7 @@ describe('ReactDOMFizzServerBrowser', () => {
);
const result = await readResult(stream);
expect(result).toMatchInlineSnapshot(
`"<link rel="preload" href="init.js" as="script" nonce="R4nd0m"/><link rel="modulepreload" href="init.mjs" nonce="R4nd0m"/><div>hello world</div><script nonce="${nonce}">INIT();</script><script src="init.js" nonce="${nonce}" async=""></script><script type="module" src="init.mjs" nonce="${nonce}" async=""></script>"`,
`"<link rel="preload" href="init.js" as="script" fetchPriority="low" nonce="R4nd0m"/><link rel="modulepreload" href="init.mjs" fetchPriority="low" nonce="R4nd0m"/><div>hello world</div><script nonce="${nonce}">INIT();</script><script src="init.js" nonce="${nonce}" async=""></script><script type="module" src="init.mjs" nonce="${nonce}" async=""></script>"`,
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ describe('ReactDOMFizzServerNode', () => {
pipe(writable);
jest.runAllTimers();
expect(output.result).toMatchInlineSnapshot(
`"<link rel="preload" href="init.js" as="script"/><link rel="modulepreload" href="init.mjs"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
`"<link rel="preload" href="init.js" as="script" fetchPriority="low"/><link rel="modulepreload" href="init.mjs" fetchPriority="low"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('ReactDOMFizzStaticBrowser', () => {
});
const prelude = await readContent(result.prelude);
expect(prelude).toMatchInlineSnapshot(
`"<link rel="preload" href="init.js" as="script"/><link rel="modulepreload" href="init.mjs"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
`"<link rel="preload" href="init.js" as="script" fetchPriority="low"/><link rel="modulepreload" href="init.mjs" fetchPriority="low"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('ReactDOMFizzStaticNode', () => {
);
const prelude = await readContent(result.prelude);
expect(prelude).toMatchInlineSnapshot(
`"<link rel="preload" href="init.js" as="script"/><link rel="modulepreload" href="init.mjs"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
`"<link rel="preload" href="init.js" as="script" fetchPriority="low"/><link rel="modulepreload" href="init.mjs" fetchPriority="low"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('ReactDOMServerFB', () => {
});
const result = readResult(stream);
expect(result).toMatchInlineSnapshot(
`"<link rel="preload" href="init.js" as="script"/><link rel="modulepreload" href="init.mjs"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
`"<link rel="preload" href="init.js" as="script" fetchPriority="low"/><link rel="modulepreload" href="init.mjs" fetchPriority="low"/><div>hello world</div><script>INIT();</script><script src="init.js" async=""></script><script type="module" src="init.mjs" async=""></script>"`,
);
});

Expand Down

0 comments on commit 8928b5e

Please sign in to comment.