diff --git a/packages/astro/src/runtime/server/render/astro/instance.ts b/packages/astro/src/runtime/server/render/astro/instance.ts index 5f6b26c728..a7745c03bb 100644 --- a/packages/astro/src/runtime/server/render/astro/instance.ts +++ b/packages/astro/src/runtime/server/render/astro/instance.ts @@ -49,23 +49,25 @@ export class AstroComponentInstance { async init(result: SSRResult) { if (this.returnValue !== undefined) return this.returnValue; this.returnValue = this.factory(result, this.props, this.slotValues); + // Save the resolved value after promise is resolved for optimization + if (isPromise(this.returnValue)) { + this.returnValue + .then((resolved) => { + this.returnValue = resolved; + }) + .catch(() => { + // Ignore errors and appease unhandledrejection error + }); + } return this.returnValue; } async render(destination: RenderDestination) { - if (this.returnValue === undefined) { - await this.init(this.result); - } - - let value: Promise | AstroFactoryReturnValue | undefined = - this.returnValue; - if (isPromise(value)) { - value = await value; - } - if (isHeadAndContent(value)) { - await value.content.render(destination); + const returnValue = await this.init(this.result); + if (isHeadAndContent(returnValue)) { + await returnValue.content.render(destination); } else { - await renderChild(destination, value); + await renderChild(destination, returnValue); } } } diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 39414591f5..469491de4e 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -12,6 +12,9 @@ const htmlEnumAttributes = /^(?:contenteditable|draggable|spellcheck|value)$/i; // Note: SVG is case-sensitive! const svgEnumAttributes = /^(?:autoReverse|externalResourcesRequired|focusable|preserveAlpha)$/i; +const AMPERSAND_REGEX = /&/g; +const DOUBLE_QUOTE_REGEX = /"/g; + const STATIC_DIRECTIVES = new Set(['set:html', 'set:text']); // converts (most) arbitrary strings to valid JS identifiers @@ -22,7 +25,9 @@ const toIdent = (k: string) => }); export const toAttributeString = (value: any, shouldEscape = true) => - shouldEscape ? String(value).replace(/&/g, '&').replace(/"/g, '"') : value; + shouldEscape + ? String(value).replace(AMPERSAND_REGEX, '&').replace(DOUBLE_QUOTE_REGEX, '"') + : value; const kebab = (k: string) => k.toLowerCase() === k ? k : k.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);