out-of-order-rendering
Rich Harris 1 day ago
parent aa547c58e5
commit eccebf01b6

@ -41,7 +41,7 @@ import { TitleElement } from './visitors/TitleElement.js';
import { UpdateExpression } from './visitors/UpdateExpression.js'; import { UpdateExpression } from './visitors/UpdateExpression.js';
import { VariableDeclaration } from './visitors/VariableDeclaration.js'; import { VariableDeclaration } from './visitors/VariableDeclaration.js';
import { SvelteBoundary } from './visitors/SvelteBoundary.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} */ /** @type {Visitors} */
const global_visitors = { const global_visitors = {

@ -323,8 +323,12 @@ export function build_inline_component(node, expression, context) {
); );
} }
if (optimiser.expressions.length > 0) { if (optimiser.is_async()) {
statement = create_async_block(b.block([optimiser.apply(), statement])); statement = create_async_block(
b.block([optimiser.apply(), statement]),
optimiser.blockers(),
optimiser.has_await
);
} }
if (dynamic && custom_css_props.length === 0) { if (dynamic && custom_css_props.length === 0) {

@ -1,5 +1,5 @@
/** @import { Expression, Identifier, Node, Statement, BlockStatement, ArrayExpression } from 'estree' */ /** @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 { ComponentContext, ServerTransformState } from '../../types.js' */
import { escape_html } from '../../../../../../escaping.js'; import { escape_html } from '../../../../../../escaping.js';
@ -299,13 +299,26 @@ export class PromiseOptimiser {
/** @type {Expression[]} */ /** @type {Expression[]} */
expressions = []; expressions = [];
has_await = false;
/** @type {Set<Expression>} */
#blockers = new Set();
/** /**
* *
* @param {Expression} expression * @param {Expression} expression
* @param {ExpressionMetadata} metadata * @param {ExpressionMetadata} metadata
*/ */
transform = (expression, metadata) => { transform = (expression, metadata) => {
for (const binding of metadata.dependencies) {
if (binding.blocker) {
this.#blockers.add(binding.blocker);
}
}
if (metadata.has_await) { if (metadata.has_await) {
this.has_await = true;
const length = this.expressions.push(expression); const length = this.expressions.push(expression);
return b.id(`$$${length - 1}`); return b.id(`$$${length - 1}`);
} }
@ -314,6 +327,10 @@ export class PromiseOptimiser {
}; };
apply() { apply() {
if (this.expressions.length === 0) {
return b.empty;
}
if (this.expressions.length === 1) { if (this.expressions.length === 1) {
return b.const('$$0', this.expressions[0]); return b.const('$$0', this.expressions[0]);
} }
@ -331,4 +348,12 @@ export class PromiseOptimiser {
b.await(b.call('Promise.all', promises)) b.await(b.call('Promise.all', promises))
); );
} }
blockers() {
return b.array([...this.#blockers]);
}
is_async() {
return this.expressions.length > 0 || this.#blockers.size > 0;
}
} }

@ -148,6 +148,8 @@ export class Renderer {
set_ssr_context(previous_context); set_ssr_context(previous_context);
} }
}); });
promises.push(promise);
} }
return promises; return promises;

Loading…
Cancel
Save