@@ -158,6 +158,9 @@ export type RenderState = {
158158 scripts : Set < ScriptResource > ,
159159 bulkPreloads : Set < PreloadResource > ,
160160
161+ // Temporarily keeps track of key to preload resources before shell flushes.
162+ preloadsMap : Map < string , PreloadResource> ,
163+
161164 // Module-global-like reference for current boundary resources
162165 boundaryResources : ?BoundaryResources ,
163166
@@ -345,6 +348,8 @@ export function createRenderState(
345348 scripts : new Set ( ) ,
346349 bulkPreloads : new Set ( ) ,
347350
351+ preloadsMap : new Map ( ) ,
352+
348353 nonce,
349354 // like a module global for currently rendering boundary
350355 boundaryResources : null ,
@@ -2134,7 +2139,7 @@ function pushLink(
21342139 let stylesInPrecedence = renderState . precedences . get ( precedence ) ;
21352140 if ( ! resumableState . stylesMap . hasOwnProperty ( key ) ) {
21362141 const resourceProps = stylesheetPropsFromRawProps ( props ) ;
2137- const preloadResource = ( undefined : void | PreloadResource ) ; // resumableState .preloadsMap.get(key); // TODO
2142+ const preloadResource = renderState . preloadsMap . get ( key ) ;
21382143 let state = NoState ;
21392144 if ( preloadResource ) {
21402145 // If we already had a preload we don't want that resource to flush directly.
@@ -2147,6 +2152,10 @@ function pushLink(
21472152 if ( preloadResource . state & Flushed ) {
21482153 state = PreloadFlushed ;
21492154 }
2155+ } else if ( resumableState . preloadsMap . hasOwnProperty ( key ) ) {
2156+ // If we resumed then we assume that this was already flushed
2157+ // by the shell.
2158+ state = PreloadFlushed ;
21502159 }
21512160 const resource = {
21522161 type : 'stylesheet ',
@@ -2518,30 +2527,37 @@ function pushImg(
25182527 // resumableState.
25192528 const { sizes } = props ;
25202529 const key = getImagePreloadKey ( src , srcSet , sizes ) ;
2530+ let resource : void | PreloadResource ;
25212531 if ( ! resumableState . preloadsMap . hasOwnProperty ( key ) ) {
2522- const resource : PreloadResource = {
2532+ const preloadProps : PreloadProps = {
2533+ rel : 'preload ',
2534+ as : 'image' ,
2535+ // There is a bug in Safari where imageSrcSet is not respected on preload links
2536+ // so we omit the href here if we have imageSrcSet b/c safari will load the wrong image.
2537+ // This harms older browers that do not support imageSrcSet by making their preloads not work
2538+ // but this population is shrinking fast and is already small so we accept this tradeoff.
2539+ href : srcSet ? undefined : src ,
2540+ imageSrcSet : srcSet ,
2541+ imageSizes : sizes ,
2542+ crossOrigin : props . crossOrigin ,
2543+ integrity : props . integrity ,
2544+ type : props . type ,
2545+ fetchPriority : props . fetchPriority ,
2546+ referrerPolicy : props . referrerPolicy ,
2547+ } ;
2548+ resource = {
25232549 type : 'preload' ,
25242550 chunks : [ ] ,
25252551 state : NoState ,
2526- props : {
2527- rel : 'preload' ,
2528- as : 'image' ,
2529- // There is a bug in Safari where imageSrcSet is not respected on preload links
2530- // so we omit the href here if we have imageSrcSet b/c safari will load the wrong image.
2531- // This harms older browers that do not support imageSrcSet by making their preloads not work
2532- // but this population is shrinking fast and is already small so we accept this tradeoff.
2533- href : srcSet ? undefined : src ,
2534- imageSrcSet : srcSet ,
2535- imageSizes : sizes ,
2536- crossOrigin : props . crossOrigin ,
2537- integrity : props . integrity ,
2538- type : props . type ,
2539- fetchPriority : props . fetchPriority ,
2540- referrerPolicy : props . referrerPolicy ,
2541- } ,
2552+ props : preloadProps ,
25422553 } ;
25432554 resumableState . preloadsMap [ key ] = null ;
2544- pushLinkImpl ( resource . chunks , resource . props ) ;
2555+ renderState . preloadsMap . set ( key , resource ) ;
2556+ pushLinkImpl ( resource . chunks , preloadProps ) ;
2557+ } else {
2558+ resource = renderState . preloadsMap . get ( key ) ;
2559+ }
2560+ if ( resource ) {
25452561 if (
25462562 props . fetchPriority === 'high' ||
25472563 renderState . highImagePreloads . size < 10
@@ -2897,7 +2913,7 @@ function pushScript(
28972913 renderState . scripts . add ( resource ) ;
28982914
28992915 let scriptProps = props ;
2900- const preloadResource = ( undefined : void | PreloadResource ) ; // resumableState .preloadsMap.get(key); // TODO
2916+ const preloadResource = renderState . preloadsMap . get ( key ) ;
29012917 if ( preloadResource ) {
29022918 // If we already had a preload we don't want that resource to flush directly.
29032919 // We let the newly created resource govern flushing.
@@ -5126,6 +5142,7 @@ function preload(href: string, as: string, options?: ?PreloadImplOptions) {
51265142 props,
51275143 } ;
51285144 resumableState . preloadsMap [ key ] = null ;
5145+ renderState . preloadsMap . set ( key , resource ) ;
51295146 pushLinkImpl ( resource . chunks , resource . props ) ;
51305147 if ( as === 'font' ) {
51315148 renderState . fontPreloads . add ( resource ) ;
@@ -5176,6 +5193,7 @@ function preloadModule(
51765193 props ,
51775194 } ;
51785195 resumableState . preloadsMap [ key ] = null ;
5196+ renderState . preloadsMap . set ( key , resource ) ;
51795197 pushLinkImpl ( resource . chunks , resource . props ) ;
51805198 renderState . bulkPreloads . add ( resource ) ;
51815199 }
@@ -5208,9 +5226,13 @@ function preinitStyle(
52085226 if ( ! resumableState . stylesMap . hasOwnProperty ( key ) ) {
52095227 precedence = precedence || 'default' ;
52105228 let state = NoState ;
5211- const preloadResource = ( undefined : void | PreloadResource ) ; // resumableState .preloadsMap.get(key); // TODO
5229+ const preloadResource = renderState . preloadsMap . get ( key ) ;
52125230 if ( preloadResource && preloadResource . state & Flushed ) {
52135231 state = PreloadFlushed ;
5232+ } else if ( resumableState . preloadsMap . hasOwnProperty ( key ) ) {
5233+ // If we resumed then we assume that this was already flushed
5234+ // by the shell.
5235+ state = PreloadFlushed ;
52145236 }
52155237 const props : StylesheetProps = Object . assign (
52165238 ( {
@@ -5382,6 +5404,7 @@ function preloadBootstrapScript(
53825404 props ,
53835405 } ;
53845406 resumableState . preloadsMap [ key ] = null ;
5407+ renderState . preloadsMap . set ( key , resource ) ;
53855408 renderState . bootstrapScripts . add ( resource ) ;
53865409 pushLinkImpl ( resource . chunks , props ) ;
53875410}
@@ -5425,6 +5448,7 @@ function preloadBootstrapModule(
54255448 props,
54265449 } ;
54275450 resumableState . preloadsMap [ key ] = null ;
5451+ renderState . preloadsMap . set ( key , resource ) ;
54285452 renderState . bootstrapScripts . add ( resource ) ;
54295453 pushLinkImpl ( resource . chunks , props ) ;
54305454 return ;
0 commit comments