diff --git a/crates/oxc_minifier/src/peephole/minimize_statements.rs b/crates/oxc_minifier/src/peephole/minimize_statements.rs index cf4f598888d9e..17d89c4520e5a 100644 --- a/crates/oxc_minifier/src/peephole/minimize_statements.rs +++ b/crates/oxc_minifier/src/peephole/minimize_statements.rs @@ -1405,13 +1405,17 @@ impl<'a> PeepholeOptimizations { ) { return Some(changed); } - if let Some(changed) = Self::substitute_single_use_symbol_in_expression( - &mut logical_expr.right, - search_for, - replacement, - replacement_has_side_effect, - ctx, - ) { + // Do not substitute our unconditionally-executed value into a branch + // unless the value itself has no side effects + if !replacement_has_side_effect + && let Some(changed) = Self::substitute_single_use_symbol_in_expression( + &mut logical_expr.right, + search_for, + replacement, + replacement_has_side_effect, + ctx, + ) + { return Some(changed); } } diff --git a/crates/oxc_minifier/tests/peephole/esbuild.rs b/crates/oxc_minifier/tests/peephole/esbuild.rs index 11d12557c1d71..6c60e2fe2f3d3 100644 --- a/crates/oxc_minifier/tests/peephole/esbuild.rs +++ b/crates/oxc_minifier/tests/peephole/esbuild.rs @@ -678,11 +678,10 @@ fn js_parser_test() { ); test("if (a) if (b) if (c) d", "a && b && c && d;"); test("if (!a) if (!b) if (!c) d", "a || b || c || d;"); - // FIXME - // test( - // "function _() { let a = foo(), b = bar(), c = baz(); return a != null ? a : b != null ? b : c }", - // "function _() { let a = foo(), b = bar(), c = baz(); return a ?? b ?? c; }", - // ); + test( + "function _() { let a = foo(), b = bar(), c = baz(); return a != null ? a : b != null ? b : c }", + "function _() { let a = foo(), b = bar(), c = baz(); return a ?? b ?? c; }", + ); test( "function _() { if (a) return c; if (b) return d; }", "function _() { if (a) return c;if (b) return d; }", @@ -1934,19 +1933,18 @@ fn test_inline_single_use_variable() { "function wrapper(arg0, arg1) { let x = fn(); return x ?? arg0;}", "function wrapper(arg0, arg1) { return fn() ?? arg0;}", ); - // FIXME - // test( - // "function wrapper(arg0, arg1) { let x = fn(); return arg0 || x;}", - // "function wrapper(arg0, arg1) { let x = fn(); return arg0 || x;}", - // ); - // test( - // "function wrapper(arg0, arg1) { let x = fn(); return arg0 && x;}", - // "function wrapper(arg0, arg1) { let x = fn(); return arg0 && x;}", - // ); - // test( - // "function wrapper(arg0, arg1) { let x = fn(); return arg0 ?? x;}", - // "function wrapper(arg0, arg1) { let x = fn(); return arg0 ?? x;}", - // ); + test( + "function wrapper(arg0, arg1) { let x = fn(); return arg0 || x;}", + "function wrapper(arg0, arg1) { let x = fn(); return arg0 || x;}", + ); + test( + "function wrapper(arg0, arg1) { let x = fn(); return arg0 && x;}", + "function wrapper(arg0, arg1) { let x = fn(); return arg0 && x;}", + ); + test( + "function wrapper(arg0, arg1) { let x = fn(); return arg0 ?? x;}", + "function wrapper(arg0, arg1) { let x = fn(); return arg0 ?? x;}", + ); test( "function wrapper(arg0, arg1) { let x = fn(); let y = x[prop]; let z = y.val; throw z}", "function wrapper(arg0, arg1) { throw fn()[prop].val;}", diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index 492d6a3526356..1b95d048528d0 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -7,21 +7,21 @@ Original | minified | minified | gzip | gzip | Iterations | Fi 287.63 kB | 89.26 kB | 90.07 kB | 30.91 kB | 31.95 kB | 2 | jquery.js -342.15 kB | 116.97 kB | 118.14 kB | 43.15 kB | 44.37 kB | 2 | vue.js +342.15 kB | 116.98 kB | 118.14 kB | 43.17 kB | 44.37 kB | 2 | vue.js -544.10 kB | 71.03 kB | 72.48 kB | 25.76 kB | 26.20 kB | 2 | lodash.js +544.10 kB | 71.04 kB | 72.48 kB | 25.78 kB | 26.20 kB | 2 | lodash.js 555.77 kB | 267.39 kB | 270.13 kB | 88.02 kB | 90.80 kB | 2 | d3.js 1.01 MB | 439.40 kB | 458.89 kB | 122.06 kB | 126.71 kB | 2 | bundle.min.js -1.25 MB | 642.65 kB | 646.76 kB | 159.38 kB | 163.73 kB | 2 | three.js +1.25 MB | 642.65 kB | 646.76 kB | 159.39 kB | 163.73 kB | 2 | three.js -2.14 MB | 711.11 kB | 724.14 kB | 160.41 kB | 181.07 kB | 2 | victory.js +2.14 MB | 711.15 kB | 724.14 kB | 160.43 kB | 181.07 kB | 2 | victory.js -3.20 MB | 1.00 MB | 1.01 MB | 322.51 kB | 331.56 kB | 3 | echarts.js +3.20 MB | 1.00 MB | 1.01 MB | 322.53 kB | 331.56 kB | 3 | echarts.js -6.69 MB | 2.22 MB | 2.31 MB | 458.38 kB | 488.28 kB | 4 | antd.js +6.69 MB | 2.22 MB | 2.31 MB | 458.41 kB | 488.28 kB | 4 | antd.js -10.95 MB | 3.33 MB | 3.49 MB | 853.27 kB | 915.50 kB | 4 | typescript.js +10.95 MB | 3.33 MB | 3.49 MB | 853.38 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 46a189a358d79..1de07ec9bfa40 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 || 83481 | 14179 || 152610 | 28185 +checker.ts | 2.92 MB || 83500 | 14179 || 152592 | 28237 -cal.com.tsx | 1.06 MB || 40446 | 3033 || 37151 | 4578 +cal.com.tsx | 1.06 MB || 40449 | 3033 || 37146 | 4583 RadixUIAdoptionSection.jsx | 2.52 kB || 85 | 9 || 30 | 6 pdf.mjs | 567.30 kB || 19808 | 2899 || 47442 | 7725 -antd.js | 6.69 MB || 99498 | 13523 || 331565 | 69251 +antd.js | 6.69 MB || 99524 | 13523 || 331573 | 69338 binder.ts | 193.08 kB || 4760 | 974 || 7075 | 824