diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js index b6c3f3dc7b..89dfe85f26 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js @@ -41,7 +41,7 @@ import { TitleElement } from './visitors/TitleElement.js'; import { UpdateExpression } from './visitors/UpdateExpression.js'; import { VariableDeclaration } from './visitors/VariableDeclaration.js'; import { SvelteBoundary } from './visitors/SvelteBoundary.js'; -import { call_component_renderer, create_async_block } from './visitors/shared/utils.js'; +import { call_component_renderer } from './visitors/shared/utils.js'; /** @type {Visitors} */ const global_visitors = { diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js index e463ea785a..e0baee9250 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js @@ -323,8 +323,12 @@ export function build_inline_component(node, expression, context) { ); } - if (optimiser.expressions.length > 0) { - statement = create_async_block(b.block([optimiser.apply(), statement])); + if (optimiser.is_async()) { + statement = create_async_block( + b.block([optimiser.apply(), statement]), + optimiser.blockers(), + optimiser.has_await + ); } if (dynamic && custom_css_props.length === 0) { diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js index 2fff258411..9d4da0b006 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js @@ -1,5 +1,5 @@ /** @import { Expression, Identifier, Node, Statement, BlockStatement, ArrayExpression } from 'estree' */ -/** @import { AST } from '#compiler' */ +/** @import { AST, Binding } from '#compiler' */ /** @import { ComponentContext, ServerTransformState } from '../../types.js' */ import { escape_html } from '../../../../../../escaping.js'; @@ -299,13 +299,26 @@ export class PromiseOptimiser { /** @type {Expression[]} */ expressions = []; + has_await = false; + + /** @type {Set} */ + #blockers = new Set(); + /** * * @param {Expression} expression * @param {ExpressionMetadata} metadata */ transform = (expression, metadata) => { + for (const binding of metadata.dependencies) { + if (binding.blocker) { + this.#blockers.add(binding.blocker); + } + } + if (metadata.has_await) { + this.has_await = true; + const length = this.expressions.push(expression); return b.id(`$$${length - 1}`); } @@ -314,6 +327,10 @@ export class PromiseOptimiser { }; apply() { + if (this.expressions.length === 0) { + return b.empty; + } + if (this.expressions.length === 1) { return b.const('$$0', this.expressions[0]); } @@ -331,4 +348,12 @@ export class PromiseOptimiser { b.await(b.call('Promise.all', promises)) ); } + + blockers() { + return b.array([...this.#blockers]); + } + + is_async() { + return this.expressions.length > 0 || this.#blockers.size > 0; + } } diff --git a/packages/svelte/src/internal/server/renderer.js b/packages/svelte/src/internal/server/renderer.js index fa7b0116d2..3562b5a60d 100644 --- a/packages/svelte/src/internal/server/renderer.js +++ b/packages/svelte/src/internal/server/renderer.js @@ -148,6 +148,8 @@ export class Renderer { set_ssr_context(previous_context); } }); + + promises.push(promise); } return promises;