@samitouri / QOS-React / commits / 535c038d15

Update preload links to support nonce and fetchpriority (#26826)

Currently when React generates rel=preload link tags for script/stylesheet resources, it will not carryover nonce and fetchpriority values if specified on the original elements. This change ensures that the preload links use the nonce and fetchPriority values if they were specified.

Yen-Wei Liu committed May 22, 2023 at 19:56 UTC 535c038d15d21f33e678187410d658456cc0ce39
2 files changed +79
packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+3
@@ -5510,6 +5510,7 @@ function preloadAsStylePropsFromProps(href: string, props: any): PreloadProps {
5510 as: 'style',
5511 href: href,
5512 crossOrigin: props.crossOrigin,
5513 + fetchPriority: props.fetchPriority,
5514 integrity: props.integrity,
5515 media: props.media,
5516 hrefLang: props.hrefLang,
@@ -5523,7 +5524,9 @@ function preloadAsScriptPropsFromProps(href: string, props: any): PreloadProps {
5524 as: 'script',
5525 href,
5526 crossOrigin: props.crossOrigin,
5527 + fetchPriority: props.fetchPriority,
5528 integrity: props.integrity,
5529 + nonce: props.nonce,
5530 referrerPolicy: props.referrerPolicy,
5531 };
5532 }
packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+76
@@ -4531,6 +4531,43 @@ body {
4531 );
4532 });
4533
4534 + // @gate enableFloat
4535 + it('respects attributes defined on the stylesheet element when preloading stylesheets during server rendering', async () => {
4536 + await act(() => {
4537 + const {pipe} = renderToPipeableStream(
4538 + <html>
4539 + <head>
4540 + <link rel="stylesheet" fetchPriority="high" href="foo" />
4541 + </head>
4542 + <body>
4543 + <link rel="stylesheet" fetchPriority="low" href="notaresource" />
4544 + <div>hello world</div>
4545 + </body>
4546 + </html>,
4547 + );
4548 + pipe(writable);
4549 + });
4550 +
4551 + expect(getMeaningfulChildren(document)).toEqual(
4552 + <html>
4553 + <head>
4554 + <link rel="preload" as="style" fetchpriority="high" href="foo" />
4555 + <link
4556 + rel="preload"
4557 + as="style"
4558 + fetchpriority="low"
4559 + href="notaresource"
4560 + />
4561 + <link rel="stylesheet" fetchpriority="high" href="foo" />
4562 + </head>
4563 + <body>
4564 + <link rel="stylesheet" fetchpriority="low" href="notaresource" />
4565 + <div>hello world</div>
4566 + </body>
4567 + </html>,
4568 + );
4569 + });
4570 +
4571 // @gate enableFloat
4572 it('hoists stylesheet resources to the correct precedence', async () => {
4573 await act(() => {
@@ -5913,6 +5950,45 @@ background-color: green;
5950 );
5951 });
5952
5953 + // @gate enableFloat
5954 + it('respects attributes defined on the script element when preloading scripts during server rendering', async () => {
5955 + await act(() => {
5956 + const {pipe} = renderToPipeableStream(
5957 + <html>
5958 + <head />
5959 + <body>
5960 + <script src="foo" fetchPriority="high" nonce="1234" />
5961 + <script src="bar" fetchPriority="low" nonce="1234" />
5962 + hello world
5963 + </body>
5964 + </html>,
5965 + );
5966 + pipe(writable);
5967 + });
5968 +
5969 + expect(getMeaningfulChildren(document)).toEqual(
5970 + <html>
5971 + <head>
5972 + <link
5973 + rel="preload"
5974 + href="foo"
5975 + fetchpriority="high"
5976 + nonce="1234"
5977 + as="script"
5978 + />
5979 + <link
5980 + rel="preload"
5981 + href="bar"
5982 + fetchpriority="low"
5983 + nonce="1234"
5984 + as="script"
5985 + />
5986 + </head>
5987 + <body>hello world</body>
5988 + </html>,
5989 + );
5990 + });
5991 +
5992 // @gate enableFloat
5993 it('does not create script resources when inside an <svg> context', async () => {
5994 await act(() => {