Repository: facebook/react
Pull request: [Fizz]: Unify preload queue

stacked on #27189

Currently React attempts to prioritize certain preloads over others based on their type. This is at odds with allowing the user to control priority by ordering which calls are made first. There are some asset types that generally should just be prioritized first such as fonts since we don't know when fonts will be used and they either block display or may lead to fallback fonts being used. But for scripts and stylesheets we can emit them in the order received with other arbitrary preload types.

We will eventually add support for emitting suspensey image preloads before other resources because these also block display however that implementation will look at which images are actually rendered rather than simply preloaded.

Changed files:
filename: packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
patch: @@ -4250,20 +4250,8 @@ export function writePreamble(
   resources.scripts.forEach(flushResourceInPreamble, destination);
   resources.scripts.clear();
 
-  resources.explicitStylesheetPreloads.forEach(
-    flushResourceInPreamble,
-    destination,
-  );
-  resources.explicitStylesheetPreloads.clear();
-
-  resources.explicitScriptPreloads.forEach(
-    flushResourceInPreamble,
-    destination,
-  );
-  resources.explicitScriptPreloads.clear();
-
-  resources.explicitOtherPreloads.forEach(flushResourceInPreamble, destination);
-  resources.explicitOtherPreloads.clear();
+  resources.explicitPreloads.forEach(flushResourceInPreamble, destination);
+  resources.explicitPreloads.clear();
 
   // Write embedding preloadChunks
   const preloadChunks = responseState.preloadChunks;
@@ -4330,14 +4318,8 @@ export function writeHoistables(
   resources.scripts.forEach(flushResourceLate, destination);
   resources.scripts.clear();
 
-  resources.explicitStylesheetPreloads.forEach(flushResourceLate, destination);
-  resources.explicitStylesheetPreloads.clear();
-
-  resources.explicitScriptPreloads.forEach(flushResourceLate, destination);
-  resources.explicitScriptPreloads.clear();
-
-  resources.explicitOtherPreloads.forEach(flushResourceLate, destination);
-  resources.explicitOtherPreloads.clear();
+  resources.explicitPreloads.forEach(flushResourceLate, destination);
+  resources.explicitPreloads.clear();
 
   // Write embedding preloadChunks
   const preloadChunks = responseState.preloadChunks;
@@ -4882,10 +4864,7 @@ export type Resources = {
   stylePrecedences: Map<string, StyleTagResource>,
   bootstrapScripts: Set<PreloadResource>,
   scripts: Set<ScriptResource>,
-  explicitStylesheetPreloads: Set<PreloadResource>,
-  // explicitImagePreloads: Set<PreloadResource>,
-  explicitScriptPreloads: Set<PreloadResource>,
-  explicitOtherPreloads: Set<PreloadResource>,
+  explicitPreloads: Set<PreloadResource>,
 
   // Module-global-like reference for current boundary resources
   boundaryResources: ?BoundaryResources,
@@ -4909,10 +4888,7 @@ export function createResources(): Resources {
     stylePrecedences: new Map(),
     bootstrapScripts: new Set(),
     scripts: new Set(),
-    explicitStylesheetPreloads: new Set(),
-    // explicitImagePreloads: new Set(),
-    explicitScriptPreloads: new Set(),
-    explicitOtherPreloads: new Set(),
+    explicitPreloads: new Set(),
 
     // like a module global for currently rendering boundary
     boundaryResources: null,
@@ -5199,22 +5175,10 @@ export function preload(href: string, options: PreloadOptions) {
 
       pushLinkImpl(resource.chunks, resource.props);
     }
-    switch (as) {
-      case 'font': {
-        resources.fontPreloads.add(resource);
-        break;
-      }
-      case 'style': {
-        resources.explicitStylesheetPreloads.add(resource);
-        break;
-      }
-      case 'script': {
-        resources.explicitScriptPreloads.add(resource);
-        break;
-      }
-      default: {
-        resources.explicitOtherPreloads.add(resource);
-      }
+    if (as === 'font') {
+      resources.fontPreloads.add(resource);
+    } else {
+      resources.explicitPreloads.add(resource);
     }
     flushResources(request);
   }

filename: packages/react-dom/src/__tests__/ReactDOMFloat-test.js
patch: @@ -4131,6 +4131,12 @@ body {
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
           <head>
+            <link
+              rel="preload"
+              as="script"
+              href="highserver"
+              fetchpriority="high"
+            />
             <link
               rel="preload"
               as="style"
@@ -4143,12 +4149,6 @@ body {
               href="autoserver"
               fetchpriority="auto"
             />
-            <link
-              rel="preload"
-              as="script"
-              href="highserver"
-              fetchpriority="high"
-            />
           </head>
           <body>hello</body>
         </html>,
@@ -4166,6 +4166,12 @@ body {
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
           <head>
+            <link
+              rel="preload"
+              as="script"
+              href="highserver"
+              fetchpriority="high"
+            />
             <link
               rel="preload"
               as="style"
@@ -4178,12 +4184,6 @@ body {
               href="autoserver"
               fetchpriority="auto"
             />
-            <link
-              rel="preload"
-              as="script"
-              href="highserver"
-              fetchpriority="high"
-            />
             <link
               rel="preload"
               as="script"