perf(minifier): update chain expressions in place (#26544)

- `try_flatten_nested_chain_expression`: deduplicate code and remove
parentheses expression as they are removed already during normalization
- `inject_optional_chaining_if_matched`, `fold_chain_expr`: mutate
expressions in place instead of creating dummy stmts first
This commit is contained in:
Armano
2026-09-12 17:16:19 +02:00
committed by GitHub
parent 0bc1661f40
commit 5b4787fb0d
4 changed files with 22 additions and 39 deletions
@@ -87,8 +87,10 @@ impl<'a> PeepholeOptimizations {
if has_optional {
ctx.notice_change();
} else {
let new_expr = Expression::from(e.expression.take_in(ctx));
ctx.replace_expression(expr, new_expr);
ctx.replace_expression_with(expr, |e, _ctx| {
let Expression::ChainExpression(e) = e else { unreachable!() };
Expression::from(e.unbox().expression)
});
}
}
ChainFold::Collapse { base, base_has_side_effects } => {
@@ -699,12 +699,9 @@ impl<'a> PeepholeOptimizations {
ctx,
) {
if !matches!(expr, Expression::ChainExpression(_)) {
let new_expr = Expression::new_chain_expression(
expr.span(),
expr.take_in(ctx).into_chain_element().unwrap(),
ctx,
);
ctx.replace_expression(expr, new_expr);
ctx.replace_expression_with(expr, |e, ctx| {
Expression::new_chain_expression(e.span(), e.into_chain_element().unwrap(), ctx)
});
}
true
} else {
@@ -1492,37 +1492,21 @@ impl<'a> PeepholeOptimizations {
expr: &mut ChainExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
match &mut expr.expression {
ChainElement::StaticMemberExpression(member) => {
if let Expression::ChainExpression(chain) = member.object.without_parentheses_mut()
{
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut member.object, new_value);
}
}
ChainElement::ComputedMemberExpression(member) => {
if let Expression::ChainExpression(chain) = member.object.without_parentheses_mut()
{
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut member.object, new_value);
}
}
ChainElement::PrivateFieldExpression(member) => {
if let Expression::ChainExpression(chain) = member.object.without_parentheses_mut()
{
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut member.object, new_value);
}
}
ChainElement::CallExpression(call) => {
if let Expression::ChainExpression(chain) = call.callee.without_parentheses_mut() {
let new_value = Expression::from(chain.expression.take_in(ctx));
ctx.replace_expression(&mut call.callee, new_value);
}
}
let object = match &mut expr.expression {
ChainElement::StaticMemberExpression(member) => &mut member.object,
ChainElement::ComputedMemberExpression(member) => &mut member.object,
ChainElement::PrivateFieldExpression(member) => &mut member.object,
ChainElement::CallExpression(call) => &mut call.callee,
ChainElement::TSNonNullExpression(_) => {
// noop
return; // noop
}
};
if matches!(object, Expression::ChainExpression(_)) {
ctx.replace_expression_with(object, |e, _ctx| {
let Expression::ChainExpression(expr) = e else { unreachable!() };
Expression::from(expr.unbox().expression)
});
}
}
@@ -49,9 +49,9 @@ antd.js:
sys deallocs: 860
sys alloc bytes: 29976375 # 29.98 MB
sys peak growth: 19934749 # 19.93 MB
arena allocs: 187331
arena allocs: 187032
arena reallocs: 63323
arena size: 43374888 # 43.37 MB
arena size: 43370040 # 43.37 MB
binder.ts:
file size: 193077 # 193.08 kB