@samitouri / QOS-React-1 / commits / 8c85b02996

[Fizz] Optimize end tags chunks (#27522)

Implements `endChunkForTag` to make writing end tags faster

Jung Yujun committed Oct 21, 2023 at 07:34 UTC 8c85b02996b940d63f961f835348a0dd0045d3b6
1 file changed +16 -15
packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+16 -15
@@ -2509,7 +2509,7 @@ function pushStyleImpl(
2509 target.push(stringToChunk(escapeTextForBrowser('' + child)));
2510 }
2511 pushInnerHTML(target, innerHTML, children);
2512 - target.push(endTag1, stringToChunk('style'), endTag2);
2512 + target.push(endChunkForTag('style'));
2513 return null;
2514 }
2515
@@ -2824,7 +2824,7 @@ function pushTitleImpl(
2824 target.push(stringToChunk(escapeTextForBrowser('' + child)));
2825 }
2826 pushInnerHTML(target, innerHTML, children);
2827 - target.push(endTag1, stringToChunk('title'), endTag2);
2827 + target.push(endChunkForTag('title'));
2828 return null;
2829 }
2830
@@ -3081,7 +3081,7 @@ function pushScriptImpl(
3081 if (typeof children === 'string') {
3082 target.push(stringToChunk(encodeHTMLTextNode(children)));
3083 }
3084 - target.push(endTag1, stringToChunk('script'), endTag2);
3084 + target.push(endChunkForTag('script'));
3085 return null;
3086 }
3087
@@ -3484,8 +3484,15 @@ export function pushStartInstance(
3484 return pushStartGenericElement(target, props, type);
3485 }
3486
3487 -const endTag1 = stringToPrecomputedChunk('</');
3488 -const endTag2 = stringToPrecomputedChunk('>');
3487 +const endTagCache = new Map<string, PrecomputedChunk>();
3488 +function endChunkForTag(tag: string): PrecomputedChunk {
3489 + let chunk = endTagCache.get(tag);
3490 + if (chunk === undefined) {
3491 + chunk = stringToPrecomputedChunk('</' + tag + '>');
3492 + endTagCache.set(tag, chunk);
3493 + }
3494 + return chunk;
3495 +}
3496
3497 export function pushEndInstance(
3498 target: Array<Chunk | PrecomputedChunk>,
@@ -3547,7 +3554,7 @@ export function pushEndInstance(
3554 }
3555 break;
3556 }
3550 - target.push(endTag1, stringToChunk(type), endTag2);
3557 + target.push(endChunkForTag(type));
3558 }
3559
3560 function writeBootstrap(
@@ -4502,9 +4509,7 @@ export function writePreamble(
4509 // if the main content contained the </head> it would also have provided a
4510 // <head>. This means that all the content inside <html> is either <body> or
4511 // invalid HTML
4505 - writeChunk(destination, endTag1);
4506 - writeChunk(destination, stringToChunk('head'));
4507 - writeChunk(destination, endTag2);
4512 + writeChunk(destination, endChunkForTag('head'));
4513 }
4514 }
4515
@@ -4577,14 +4582,10 @@ export function writePostamble(
4582 resumableState: ResumableState,
4583 ): void {
4584 if (resumableState.hasBody) {
4580 - writeChunk(destination, endTag1);
4581 - writeChunk(destination, stringToChunk('body'));
4582 - writeChunk(destination, endTag2);
4585 + writeChunk(destination, endChunkForTag('body'));
4586 }
4587 if (resumableState.hasHtml) {
4585 - writeChunk(destination, endTag1);
4586 - writeChunk(destination, stringToChunk('html'));
4587 - writeChunk(destination, endTag2);
4588 + writeChunk(destination, endChunkForTag('html'));
4589 }
4590 }
4591