Skip to content

rel=expect playground #33448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 34 additions & 23 deletions fixtures/fizz/server/render-to-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,40 @@ module.exports = function render(url, res) {
});
let didError = false;
let didFinish = false;
const {pipe, abort} = renderToPipeableStream(<App assets={assets} />, {
bootstrapScripts: [assets['main.js']],
onAllReady() {
// Full completion.
// You can use this for SSG or crawlers.
didFinish = true;
},
onShellReady() {
// If something errored before we started streaming, we set the error code appropriately.
res.statusCode = didError ? 500 : 200;
res.setHeader('Content-type', 'text/html');
setImmediate(() => pipe(res));
},
onShellError(x) {
// Something errored before we could complete the shell so we emit an alternative shell.
res.statusCode = 500;
res.send('<!doctype><p>Error</p>');
},
onError(x) {
didError = true;
console.error(x);
},
});
const {pipe, abort} = renderToPipeableStream(
<App
assets={assets}
delay={
new Promise(resolve => {
setTimeout(resolve, 5000);
})
}
/>,
{
bootstrapScripts: [assets['main.js']],
onAllReady() {
// Full completion.
// You can use this for SSG or crawlers.
didFinish = true;
},
onShellReady() {
// If something errored before we started streaming, we set the error code appropriately.
res.statusCode = didError ? 500 : 200;
res.setHeader('Content-type', 'text/html');
setImmediate(() => pipe(res));
},
onShellError(x) {
// Something errored before we could complete the shell so we emit an alternative shell.
res.statusCode = 500;
res.send('<!doctype><p>Error</p>');
},
onError(x) {
didError = true;
console.error(x);
},
progressiveChunkSize: 1024,
}
);
// Abandon and switch to client rendering if enough time passes.
// Try lowering this to see the client recover.
setTimeout(() => {
Expand Down
20 changes: 18 additions & 2 deletions fixtures/fizz/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,28 @@

import Html from './Html';
import BigComponent from './BigComponent';
import React, {
Fragment,
Suspense,
unstable_SuspenseList as SuspenseList,
} from 'react';

export default function App({assets, title}) {
function Use({usable}) {
usable && React.use(usable);
return null;
}

export default function App({assets, title, delay}) {
const components = [];

for (let i = 0; i <= 250; i++) {
components.push(<BigComponent key={i} />);
components.push(
// Replace Suspense with Fragment to push rel=expect to bottom and degrade FCP
<Fragment key={i}>
<BigComponent />
<Use usable={delay} />
</Fragment>
);
}

return (
Expand Down
18 changes: 18 additions & 0 deletions fixtures/fizz/src/Html.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,24 @@ export default function Html({assets, children, title}) {
<link rel="shortcut icon" href="favicon.ico" />
<link rel="stylesheet" href={assets['main.css']} />
<title>{title}</title>
<script
dangerouslySetInnerHTML={{
__html: `
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(
\`The time to \${entry.name} was \${entry.startTime} milliseconds.\`,
);
// Logs "The time to first-paint was 386.7999999523163 milliseconds."
// Logs "The time to first-contentful-paint was 400.6999999284744 milliseconds."
});
});

observer.observe({ type: "paint", buffered: true });

`,
}}
/>
</head>
<body>
<noscript
Expand Down
40 changes: 14 additions & 26 deletions fixtures/fizz/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3176,7 +3176,7 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=

"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
Expand Down Expand Up @@ -3300,13 +3300,6 @@ lodash@^4.17.15, lodash@^4.17.19:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==

loose-envify@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"

lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
Expand Down Expand Up @@ -4095,13 +4088,12 @@ rc@^1.2.8:
minimist "^1.2.0"
strip-json-comments "~2.0.1"

react-dom@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
react-dom@^19.0.0:
version "19.1.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.1.0.tgz#133558deca37fa1d682708df8904b25186793623"
integrity sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.0"
scheduler "^0.26.0"

react-error-boundary@^3.1.3:
version "3.1.4"
Expand All @@ -4110,12 +4102,10 @@ react-error-boundary@^3.1.3:
dependencies:
"@babel/runtime" "^7.12.5"

react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
react@^19.0.0:
version "19.1.0"
resolved "https://registry.yarnpkg.com/react/-/react-19.1.0.tgz#926864b6c48da7627f004795d6cce50e90793b75"
integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==

read-pkg@^4.0.1:
version "4.0.1"
Expand Down Expand Up @@ -4383,12 +4373,10 @@ safe-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==

scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies:
loose-envify "^1.1.0"
scheduler@^0.26.0:
version "0.26.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.26.0.tgz#4ce8a8c2a2095f13ea11bf9a445be50c555d6337"
integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==

schema-utils@^1.0.0:
version "1.0.0"
Expand Down
Loading