Skip to content

Commit

Permalink
[Fizz] Encode external fizz runtime into chunks eagerly (#26752)
Browse files Browse the repository at this point in the history
in #26738 we added nonce to the
ResponseState. Initially it was used in a variety of places but the
version that got merged only included it with the external fizz runtime.
This PR updates the config for the external fizz runtime so that the
nonce is encoded into the script chunks at request creation time.

The rationale is that for live-requests, streaming is more likely than
not so doing the encoding work at the start is better than during flush.
For cases such as SSG where the runtime is not required the extra
encoding is tolerable (not a live request). Bots are an interesting case
because if you want fastest TTFB you will end up requiring the runtime
but if you are withholding until the stream is done you have already
sacrificed fastest TTFB and the marginal slowdown of the extraneous
encoding is hopefully neglibible

I'm writing this so later if we learn that this tradeoff isn't worth it
we at least understand why I made the change in the first place.

DiffTrain build for [8ea96ef](8ea96ef)
  • Loading branch information
gnoff committed May 1, 2023
1 parent 655915c commit cae0d1b
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 175 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
491aec5d6113ce5bae7c10966bc38a4a8fc091a8
8ea96ef84d8f08ed1846dec9e8ed20d2225db0d3
58 changes: 32 additions & 26 deletions compiled/facebook-www/ReactDOMServer-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");

var ReactVersion = "18.3.0-www-classic-cc24eed6";
var ReactVersion = "18.3.0-www-classic-fcee71d2";

// This refers to a WWW module.
var warningWWW = require("warning");
Expand Down Expand Up @@ -2415,7 +2415,7 @@ function createResponseState$1(
'<script nonce="' + escapeTextForBrowser(nonce) + '">'
);
var bootstrapChunks = [];
var externalRuntimeDesc = null;
var externalRuntimeScript = null;
var streamingFormat = ScriptStreamingFormat;

if (bootstrapScriptContent !== undefined) {
Expand All @@ -2431,12 +2431,27 @@ function createResponseState$1(
streamingFormat = DataStreamingFormat;

if (typeof externalRuntimeConfig === "string") {
externalRuntimeDesc = {
externalRuntimeScript = {
src: externalRuntimeConfig,
integrity: undefined
chunks: []
};
pushScriptImpl(externalRuntimeScript.chunks, {
src: externalRuntimeConfig,
async: true,
integrity: undefined,
nonce: nonce
});
} else {
externalRuntimeDesc = externalRuntimeConfig;
externalRuntimeScript = {
src: externalRuntimeConfig.src,
chunks: []
};
pushScriptImpl(externalRuntimeScript.chunks, {
src: externalRuntimeConfig.src,
async: true,
integrity: externalRuntimeConfig.integrity,
nonce: nonce
});
}
}
}
Expand Down Expand Up @@ -2514,7 +2529,7 @@ function createResponseState$1(
streamingFormat: streamingFormat,
startInlineScript: inlineScriptWithNonce,
instructions: NothingSent,
externalRuntimeConfig: externalRuntimeDesc,
externalRuntimeScript: externalRuntimeScript,
htmlChunks: null,
headChunks: null,
hasBody: false,
Expand Down Expand Up @@ -6194,16 +6209,16 @@ function writePreamble(
willFlushAllSegments
) {
// This function must be called exactly once on every request
if (!willFlushAllSegments && responseState.externalRuntimeConfig) {
if (!willFlushAllSegments && responseState.externalRuntimeScript) {
// If the root segment is incomplete due to suspended tasks
// (e.g. willFlushAllSegments = false) and we are using data
// streaming format, ensure the external runtime is sent.
// (User code could choose to send this even earlier by calling
// preinit(...), if they know they will suspend).
var _responseState$extern = responseState.externalRuntimeConfig,
var _responseState$extern = responseState.externalRuntimeScript,
src = _responseState$extern.src,
integrity = _responseState$extern.integrity;
internalPreinitScript(resources, src, integrity, responseState.nonce);
chunks = _responseState$extern.chunks;
internalPreinitScript(resources, src, chunks);
}

var htmlChunks = responseState.htmlChunks;
Expand Down Expand Up @@ -6258,10 +6273,10 @@ function writePreamble(

if (resources.stylesMap.has(key));
else {
var chunks = resource.chunks;
var _chunks = resource.chunks;

for (i = 0; i < chunks.length; i++) {
writeChunk(destination, chunks[i]);
for (i = 0; i < _chunks.length; i++) {
writeChunk(destination, _chunks[i]);
}
}
});
Expand Down Expand Up @@ -7425,29 +7440,21 @@ function preinit(href, options) {
}
}
}
} // This method is trusted. It must only be called from within this codebase and it assumes the arguments
// conform to the types because no user input is being passed in. It also assumes that it is being called as
// part of a work or flush loop and therefore does not need to request Fizz to flush Resources.
}

function internalPreinitScript(resources, src, integrity, nonce) {
function internalPreinitScript(resources, src, chunks) {
var key = getResourceKey("script", src);
var resource = resources.scriptsMap.get(key);

if (!resource) {
resource = {
type: "script",
chunks: [],
chunks: chunks,
state: NoState,
props: null
};
resources.scriptsMap.set(key, resource);
resources.scripts.add(resource);
pushScriptImpl(resource.chunks, {
async: true,
src: src,
integrity: integrity,
nonce: nonce
});
}

return;
Expand Down Expand Up @@ -7627,7 +7634,7 @@ function createResponseState(
streamingFormat: responseState.streamingFormat,
startInlineScript: responseState.startInlineScript,
instructions: responseState.instructions,
externalRuntimeConfig: responseState.externalRuntimeConfig,
externalRuntimeScript: responseState.externalRuntimeScript,
htmlChunks: responseState.htmlChunks,
headChunks: responseState.headChunks,
hasBody: responseState.hasBody,
Expand All @@ -7636,7 +7643,6 @@ function createResponseState(
preloadChunks: responseState.preloadChunks,
hoistableChunks: responseState.hoistableChunks,
stylesToHoist: responseState.stylesToHoist,
nonce: responseState.nonce,
// This is an extra field for the legacy renderer
generateStaticMarkup: generateStaticMarkup
};
Expand Down
58 changes: 32 additions & 26 deletions compiled/facebook-www/ReactDOMServer-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");

var ReactVersion = "18.3.0-www-modern-10c90c32";
var ReactVersion = "18.3.0-www-modern-938c86f0";

// This refers to a WWW module.
var warningWWW = require("warning");
Expand Down Expand Up @@ -2415,7 +2415,7 @@ function createResponseState$1(
'<script nonce="' + escapeTextForBrowser(nonce) + '">'
);
var bootstrapChunks = [];
var externalRuntimeDesc = null;
var externalRuntimeScript = null;
var streamingFormat = ScriptStreamingFormat;

if (bootstrapScriptContent !== undefined) {
Expand All @@ -2431,12 +2431,27 @@ function createResponseState$1(
streamingFormat = DataStreamingFormat;

if (typeof externalRuntimeConfig === "string") {
externalRuntimeDesc = {
externalRuntimeScript = {
src: externalRuntimeConfig,
integrity: undefined
chunks: []
};
pushScriptImpl(externalRuntimeScript.chunks, {
src: externalRuntimeConfig,
async: true,
integrity: undefined,
nonce: nonce
});
} else {
externalRuntimeDesc = externalRuntimeConfig;
externalRuntimeScript = {
src: externalRuntimeConfig.src,
chunks: []
};
pushScriptImpl(externalRuntimeScript.chunks, {
src: externalRuntimeConfig.src,
async: true,
integrity: externalRuntimeConfig.integrity,
nonce: nonce
});
}
}
}
Expand Down Expand Up @@ -2514,7 +2529,7 @@ function createResponseState$1(
streamingFormat: streamingFormat,
startInlineScript: inlineScriptWithNonce,
instructions: NothingSent,
externalRuntimeConfig: externalRuntimeDesc,
externalRuntimeScript: externalRuntimeScript,
htmlChunks: null,
headChunks: null,
hasBody: false,
Expand Down Expand Up @@ -6194,16 +6209,16 @@ function writePreamble(
willFlushAllSegments
) {
// This function must be called exactly once on every request
if (!willFlushAllSegments && responseState.externalRuntimeConfig) {
if (!willFlushAllSegments && responseState.externalRuntimeScript) {
// If the root segment is incomplete due to suspended tasks
// (e.g. willFlushAllSegments = false) and we are using data
// streaming format, ensure the external runtime is sent.
// (User code could choose to send this even earlier by calling
// preinit(...), if they know they will suspend).
var _responseState$extern = responseState.externalRuntimeConfig,
var _responseState$extern = responseState.externalRuntimeScript,
src = _responseState$extern.src,
integrity = _responseState$extern.integrity;
internalPreinitScript(resources, src, integrity, responseState.nonce);
chunks = _responseState$extern.chunks;
internalPreinitScript(resources, src, chunks);
}

var htmlChunks = responseState.htmlChunks;
Expand Down Expand Up @@ -6258,10 +6273,10 @@ function writePreamble(

if (resources.stylesMap.has(key));
else {
var chunks = resource.chunks;
var _chunks = resource.chunks;

for (i = 0; i < chunks.length; i++) {
writeChunk(destination, chunks[i]);
for (i = 0; i < _chunks.length; i++) {
writeChunk(destination, _chunks[i]);
}
}
});
Expand Down Expand Up @@ -7425,29 +7440,21 @@ function preinit(href, options) {
}
}
}
} // This method is trusted. It must only be called from within this codebase and it assumes the arguments
// conform to the types because no user input is being passed in. It also assumes that it is being called as
// part of a work or flush loop and therefore does not need to request Fizz to flush Resources.
}

function internalPreinitScript(resources, src, integrity, nonce) {
function internalPreinitScript(resources, src, chunks) {
var key = getResourceKey("script", src);
var resource = resources.scriptsMap.get(key);

if (!resource) {
resource = {
type: "script",
chunks: [],
chunks: chunks,
state: NoState,
props: null
};
resources.scriptsMap.set(key, resource);
resources.scripts.add(resource);
pushScriptImpl(resource.chunks, {
async: true,
src: src,
integrity: integrity,
nonce: nonce
});
}

return;
Expand Down Expand Up @@ -7627,7 +7634,7 @@ function createResponseState(
streamingFormat: responseState.streamingFormat,
startInlineScript: responseState.startInlineScript,
instructions: responseState.instructions,
externalRuntimeConfig: responseState.externalRuntimeConfig,
externalRuntimeScript: responseState.externalRuntimeScript,
htmlChunks: responseState.htmlChunks,
headChunks: responseState.headChunks,
hasBody: responseState.hasBody,
Expand All @@ -7636,7 +7643,6 @@ function createResponseState(
preloadChunks: responseState.preloadChunks,
hoistableChunks: responseState.hoistableChunks,
stylesToHoist: responseState.stylesToHoist,
nonce: responseState.nonce,
// This is an extra field for the legacy renderer
generateStaticMarkup: generateStaticMarkup
};
Expand Down
Loading

0 comments on commit cae0d1b

Please sign in to comment.