From ad310aaf2d12e0649052bd7107f7afb4d3af303f Mon Sep 17 00:00:00 2001 From: armano Date: Thu, 1 Jan 2026 14:13:55 +0100 Subject: [PATCH] feat(minifier): do not flip if/else when it would produce longer result --- .../src/peephole/minimize_conditions.rs | 20 +++++++++----- .../src/peephole/minimize_if_statement.rs | 26 ++++++++++++++----- tasks/minsize/minsize.snap | 8 +++--- .../allocs_minifier.snap | 6 ++--- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/crates/oxc_minifier/src/peephole/minimize_conditions.rs b/crates/oxc_minifier/src/peephole/minimize_conditions.rs index 26ff09e6658af..5d875c4028623 100644 --- a/crates/oxc_minifier/src/peephole/minimize_conditions.rs +++ b/crates/oxc_minifier/src/peephole/minimize_conditions.rs @@ -637,13 +637,21 @@ mod test { if (!x) { for (;;) foo(); for (;;) bar(); - } else if (y) for (;;) f();", + } else for (;;) f();", " - if (x) { - if (y) for (; ; ) f(); - } else { - for (; ; ) foo(); - for (; ; ) bar();}", + if (x) for (;;) f(); + else { + for (;;) foo(); + for (;;) bar(); + } + ", + ); + test_same( + " + if (!x) { + for (;;) foo(); + for (;;) bar(); + } else if (y) for (;;) f();", ); test_same("if(!a&&!b) {for(;;)foo(); for(;;)bar()} else if(y) for(;;) f()"); } diff --git a/crates/oxc_minifier/src/peephole/minimize_if_statement.rs b/crates/oxc_minifier/src/peephole/minimize_if_statement.rs index a56ab4dfc4943..c444b643e7ceb 100644 --- a/crates/oxc_minifier/src/peephole/minimize_if_statement.rs +++ b/crates/oxc_minifier/src/peephole/minimize_if_statement.rs @@ -89,7 +89,8 @@ impl<'a> PeepholeOptimizations { // "yes" is not missing (and is not an expression) if let Some(alternate) = &mut if_stmt.alternate { // "yes" is not missing (and is not an expression) and "no" is not missing - if let Expression::UnaryExpression(unary_expr) = &mut if_stmt.test + if !matches!(alternate, Statement::IfStatement(_)) + && let Expression::UnaryExpression(unary_expr) = &mut if_stmt.test && unary_expr.operator.is_not() { // "if (!a) return b; else return c;" => "if (a) return c; else return b;" @@ -98,6 +99,7 @@ impl<'a> PeepholeOptimizations { Self::wrap_to_avoid_ambiguous_else(if_stmt, ctx); ctx.state.changed = true; } + // "if (!a) {} else if (b) {}" => "if (!a) {} if (b) {}" is handled by minimize_statements // "if (a) return b; else {}" => "if (a) return b;" is handled by remove_dead_code } else { // "no" is missing @@ -169,6 +171,19 @@ mod test { }", ); + test( + "function bar() { + if (!x) { + return null; + } else { + return foo; + } + }", + "function bar() { + return x ? foo : null; + }", + ); + test( "function bar() { if (!x) { @@ -180,12 +195,9 @@ mod test { } }", "function bar() { - if (x) { - if (y) - return foo; - if (z) - return bar; - } else return null; + if (!x) return null; + if (y) return foo; + if (z) return bar; }", ); diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index 1baa98af471ad..47600cf01fd3b 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -13,15 +13,15 @@ Original | minified | minified | gzip | gzip | Iterations | Fi 555.77 kB | 267.39 kB | 270.13 kB | 88.00 kB | 90.80 kB | 2 | d3.js -1.01 MB | 439.38 kB | 458.89 kB | 122.06 kB | 126.71 kB | 2 | bundle.min.js +1.01 MB | 439.37 kB | 458.89 kB | 122.06 kB | 126.71 kB | 2 | bundle.min.js 1.25 MB | 642.66 kB | 646.76 kB | 159.40 kB | 163.73 kB | 2 | three.js -2.14 MB | 711.14 kB | 724.14 kB | 160.43 kB | 181.07 kB | 2 | victory.js +2.14 MB | 711.11 kB | 724.14 kB | 160.43 kB | 181.07 kB | 2 | victory.js -3.20 MB | 1.00 MB | 1.01 MB | 322.59 kB | 331.56 kB | 3 | echarts.js +3.20 MB | 1.00 MB | 1.01 MB | 322.58 kB | 331.56 kB | 3 | echarts.js 6.69 MB | 2.22 MB | 2.31 MB | 458.44 kB | 488.28 kB | 4 | antd.js -10.95 MB | 3.33 MB | 3.49 MB | 853.36 kB | 915.50 kB | 4 | typescript.js +10.95 MB | 3.33 MB | 3.49 MB | 853.32 kB | 915.50 kB | 4 | typescript.js diff --git a/tasks/track_memory_allocations/allocs_minifier.snap b/tasks/track_memory_allocations/allocs_minifier.snap index 94eca5ee1ee0f..58485ca6f7b67 100644 --- a/tasks/track_memory_allocations/allocs_minifier.snap +++ b/tasks/track_memory_allocations/allocs_minifier.snap @@ -1,14 +1,14 @@ File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs | Arena bytes ------------------------------------------------------------------------------------------------------------------------------------------- -checker.ts | 2.92 MB || 83502 | 14179 || 152592 | 28237 +checker.ts | 2.92 MB || 83504 | 14179 || 152600 | 28244 cal.com.tsx | 1.06 MB || 40447 | 3032 || 37138 | 4586 RadixUIAdoptionSection.jsx | 2.52 kB || 85 | 9 || 30 | 6 -pdf.mjs | 567.30 kB || 20193 | 2899 || 47453 | 7730 +pdf.mjs | 567.30 kB || 20194 | 2899 || 47464 | 7730 -antd.js | 6.69 MB || 99534 | 13524 || 331649 | 69358 +antd.js | 6.69 MB || 99534 | 13524 || 331648 | 69358 binder.ts | 193.08 kB || 4759 | 974 || 7075 | 824