Skip to content

Commit

Permalink
[Float][Fiber] Assume stylesheets in document are already loaded (#29811
Browse files Browse the repository at this point in the history
)

When we made stylesheets suspend even during high priority updates we
exposed a bug in the loading tracking of stylesheets that are loaded as
part of the preamble. This allowed these stylesheets to put suspense
boundaries into fallback mode more often than expected because cases
where a stylesheet was server rendered could now cause a fallback to
trigger which was never intended to happen.

This fix updates resource construction to evaluate whether the instance
exists in the DOM prior to construction and if so marks the resource as
loaded and inserted.

One ambiguity that needed to be solved still is how to tell whether a
stylesheet rendered as part of a late Suspense boundary reveal is
already loaded. I updated the instruction to clear out the loading
promise after successfully loading. This is useful because later if we
encounter this same resource again we can avoid the microtask if it is
already loaded. It also means that we can concretely understand that if
a stylesheet is in the DOM without this marker then it must have loaded
(or errored) already.

DiffTrain build for [20b6f4c](20b6f4c)
  • Loading branch information
gnoff committed Jun 7, 2024
1 parent cdfa569 commit 19bb867
Show file tree
Hide file tree
Showing 37 changed files with 526 additions and 443 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20841f9a6205a633e6d08a274db974481daaca23
20b6f4c0e8a1f40ee61735201645e0395ff08f94
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION_TRANSFORMS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20841f9a6205a633e6d08a274db974481daaca23
20b6f4c0e8a1f40ee61735201645e0395ff08f94
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ if (
) {
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
}
var ReactVersion = '19.0.0-www-classic-20841f9a62-20240607';
var ReactVersion = '19.0.0-www-classic-20b6f4c0e8-20240607';

// Re-export dynamic flags from the www version.
var dynamicFeatureFlags = require('ReactFeatureFlags');
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ if (
) {
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
}
var ReactVersion = '19.0.0-www-modern-20841f9a62-20240607';
var ReactVersion = '19.0.0-www-modern-20b6f4c0e8-20240607';

// Re-export dynamic flags from the www version.
var dynamicFeatureFlags = require('ReactFeatureFlags');
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -665,4 +665,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-classic-20841f9a62-20240607";
exports.version = "19.0.0-www-classic-20b6f4c0e8-20240607";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -665,4 +665,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-modern-20841f9a62-20240607";
exports.version = "19.0.0-www-modern-20b6f4c0e8-20240607";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-classic-20841f9a62-20240607";
exports.version = "19.0.0-www-classic-20b6f4c0e8-20240607";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-www-modern-20841f9a62-20240607";
exports.version = "19.0.0-www-modern-20b6f4c0e8-20240607";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactART-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function _assertThisInitialized(self) {
return self;
}

var ReactVersion = '19.0.0-www-classic-20841f9a62-20240607';
var ReactVersion = '19.0.0-www-classic-20b6f4c0e8-20240607';

var LegacyRoot = 0;
var ConcurrentRoot = 1;
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactART-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function _assertThisInitialized(self) {
return self;
}

var ReactVersion = '19.0.0-www-modern-20841f9a62-20240607';
var ReactVersion = '19.0.0-www-modern-20b6f4c0e8-20240607';

var LegacyRoot = 0;
var ConcurrentRoot = 1;
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -10686,7 +10686,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "19.0.0-www-classic-20841f9a62-20240607",
version: "19.0.0-www-classic-20b6f4c0e8-20240607",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1371 = {
Expand Down Expand Up @@ -10717,7 +10717,7 @@ var internals$jscomp$inline_1371 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-classic-20841f9a62-20240607"
reconcilerVersion: "19.0.0-www-classic-20b6f4c0e8-20240607"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1372 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -10149,7 +10149,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "19.0.0-www-modern-20841f9a62-20240607",
version: "19.0.0-www-modern-20b6f4c0e8-20240607",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1357 = {
Expand Down Expand Up @@ -10180,7 +10180,7 @@ var internals$jscomp$inline_1357 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-www-modern-20841f9a62-20240607"
reconcilerVersion: "19.0.0-www-modern-20b6f4c0e8-20240607"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1358 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
64 changes: 37 additions & 27 deletions compiled/facebook-www/ReactDOM-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -31169,7 +31169,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}

var ReactVersion = '19.0.0-www-classic-20841f9a62-20240607';
var ReactVersion = '19.0.0-www-classic-20b6f4c0e8-20240607';

function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
implementation) {
Expand Down Expand Up @@ -39475,8 +39475,25 @@ function getResource(type, currentProps, pendingProps, currentResource) {

_styles.set(_key, _resource);

var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(_key));

if (instance) {
var loadingState = instance._p;

if (loadingState) ; else {
// This instance is already loaded
_resource.instance = instance;
_resource.state.loading = Loaded | Inserted;
}
}

if (!preloadPropsMap.has(_key)) {
preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state);
var preloadProps = preloadPropsFromStylesheet(qualifiedProps);
preloadPropsMap.set(_key, preloadProps);

if (!instance) {
preloadStylesheet(ownerDocument, _key, preloadProps, _resource.state);
}
}
}

Expand Down Expand Up @@ -39623,31 +39640,24 @@ function stylesheetPropsFromRawProps(rawProps) {
}

function preloadStylesheet(ownerDocument, key, preloadProps, state) {
preloadPropsMap.set(key, preloadProps);

if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) {
// There is no matching stylesheet instance in the Document.
// We will insert a preload now to kick off loading because
// we expect this stylesheet to commit
var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key));

if (preloadEl) {
// If we find a preload already it was SSR'd and we won't have an actual
// loading state to track. For now we will just assume it is loaded
state.loading = Loaded;
} else {
var instance = ownerDocument.createElement('link');
state.preload = instance;
instance.addEventListener('load', function () {
return state.loading |= Loaded;
});
instance.addEventListener('error', function () {
return state.loading |= Errored;
});
setInitialProperties(instance, 'link', preloadProps);
markNodeAsHoistable(instance);
ownerDocument.head.appendChild(instance);
}
var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key));

if (preloadEl) {
// If we find a preload already it was SSR'd and we won't have an actual
// loading state to track. For now we will just assume it is loaded
state.loading = Loaded;
} else {
var instance = ownerDocument.createElement('link');
state.preload = instance;
instance.addEventListener('load', function () {
return state.loading |= Loaded;
});
instance.addEventListener('error', function () {
return state.loading |= Errored;
});
setInitialProperties(instance, 'link', preloadProps);
markNodeAsHoistable(instance);
ownerDocument.head.appendChild(instance);
}
}

Expand Down
64 changes: 37 additions & 27 deletions compiled/facebook-www/ReactDOM-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -30321,7 +30321,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}

var ReactVersion = '19.0.0-www-modern-20841f9a62-20240607';
var ReactVersion = '19.0.0-www-modern-20b6f4c0e8-20240607';

function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
implementation) {
Expand Down Expand Up @@ -38605,8 +38605,25 @@ function getResource(type, currentProps, pendingProps, currentResource) {

_styles.set(_key, _resource);

var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(_key));

if (instance) {
var loadingState = instance._p;

if (loadingState) ; else {
// This instance is already loaded
_resource.instance = instance;
_resource.state.loading = Loaded | Inserted;
}
}

if (!preloadPropsMap.has(_key)) {
preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state);
var preloadProps = preloadPropsFromStylesheet(qualifiedProps);
preloadPropsMap.set(_key, preloadProps);

if (!instance) {
preloadStylesheet(ownerDocument, _key, preloadProps, _resource.state);
}
}
}

Expand Down Expand Up @@ -38753,31 +38770,24 @@ function stylesheetPropsFromRawProps(rawProps) {
}

function preloadStylesheet(ownerDocument, key, preloadProps, state) {
preloadPropsMap.set(key, preloadProps);

if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) {
// There is no matching stylesheet instance in the Document.
// We will insert a preload now to kick off loading because
// we expect this stylesheet to commit
var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key));

if (preloadEl) {
// If we find a preload already it was SSR'd and we won't have an actual
// loading state to track. For now we will just assume it is loaded
state.loading = Loaded;
} else {
var instance = ownerDocument.createElement('link');
state.preload = instance;
instance.addEventListener('load', function () {
return state.loading |= Loaded;
});
instance.addEventListener('error', function () {
return state.loading |= Errored;
});
setInitialProperties(instance, 'link', preloadProps);
markNodeAsHoistable(instance);
ownerDocument.head.appendChild(instance);
}
var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key));

if (preloadEl) {
// If we find a preload already it was SSR'd and we won't have an actual
// loading state to track. For now we will just assume it is loaded
state.loading = Loaded;
} else {
var instance = ownerDocument.createElement('link');
state.preload = instance;
instance.addEventListener('load', function () {
return state.loading |= Loaded;
});
instance.addEventListener('error', function () {
return state.loading |= Errored;
});
setInitialProperties(instance, 'link', preloadProps);
markNodeAsHoistable(instance);
ownerDocument.head.appendChild(instance);
}
}

Expand Down
Loading

0 comments on commit 19bb867

Please sign in to comment.