Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/oxc_minifier/src/peephole/minimize_statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,13 @@ impl<'a> PeepholeOptimizations {
*target_expr = replacement.take_in(ctx.ast);
return Some(true);
}
// If the identifier is not a getter and the identifier is read-only,
// we know that the value is same even if we reordered the expression.
if let Some(symbol_id) = ctx.scoping().get_reference(id.reference_id()).symbol_id()
&& !ctx.scoping().symbol_is_mutated(symbol_id)
{
return None;
}
}
Expression::AwaitExpression(await_expr) => {
if let Some(changed) = Self::substitute_single_use_symbol_in_expression(
Expand Down
38 changes: 20 additions & 18 deletions crates/oxc_minifier/tests/peephole/esbuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,10 +678,11 @@ 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;");
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; }",
);
// 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 _() { if (a) return c; if (b) return d; }",
"function _() { if (a) return c;if (b) return d; }",
Expand Down Expand Up @@ -1730,8 +1731,8 @@ fn test_inline_single_use_variable() {
"function wrapper(arg0, arg1) { return fn() + arg0;}",
);
test(
"function wrapper(arg0, arg1) { let x = fn(); return arg0 + x}",
"function wrapper(arg0, arg1) { let x = fn(); return arg0 + x;}",
"function wrapper(arg0, arg1) { let x = fn(); return arg0.a + x}",
"function wrapper(arg0, arg1) { let x = fn(); return arg0.a + x;}",
);
test(
"function wrapper(arg0, arg1) { let x = fn(); return x + fn2()}",
Expand Down Expand Up @@ -1933,18 +1934,19 @@ fn test_inline_single_use_variable() {
"function wrapper(arg0, arg1) { let x = fn(); return x ?? arg0;}",
"function wrapper(arg0, arg1) { return fn() ?? arg0;}",
);
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;}",
);
// 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(); let y = x[prop]; let z = y.val; throw z}",
"function wrapper(arg0, arg1) { throw fn()[prop].val;}",
Expand Down
26 changes: 26 additions & 0 deletions crates/oxc_minifier/tests/peephole/inline_single_use_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,32 @@ fn test_inline_single_use_variable() {
);
}

#[test]
fn test_inline_past_readonly_variable() {
test(
"function wrapper() { var x = foo, y = bar; return [x, y] }",
"function wrapper() { return [foo, bar] }",
);
test(
"function wrapper() { function x() {} var y = bar; return [x, y] }",
"function wrapper() { function x() {} return [x, bar] }",
);
test_same(
"function wrapper(bar) { Object.defineProperty(globalThis, 'foo', { value: () => { y = 1 } }); var x = foo, y = bar; return [x, y] }",
);
test_same(
"function wrapper(foo) { Object.defineProperty(globalThis, 'bar', { value: () => { x = 1 } }); var x = foo, y = bar; return [x, y] }",
);
test(
"function wrapper(bar) { var foo = { get bar() { y = 1 } }, x = foo.bar, y = bar; return [x, y] }",
"function wrapper(bar) { var x = { get bar() { y = 1 } }.bar, y = bar; return [x, y] }",
);
test(
"function wrapper(foo) { var bar = { get baz() { x = 1 } }, x = foo, y = bar.baz; return [x, y] }",
"function wrapper(foo) { var bar = { get baz() { x = 1 } }, x = foo, y = bar.baz; return [x, y] }",
);
}

#[test]
fn test_within_same_variable_declarations() {
test_script(
Expand Down
22 changes: 11 additions & 11 deletions tasks/minsize/minsize.snap
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
| Oxc | ESBuild | Oxc | ESBuild |
Original | minified | minified | gzip | gzip | Iterations | File
-------------------------------------------------------------------------------------
72.14 kB | 23.21 kB | 23.70 kB | 8.38 kB | 8.54 kB | 2 | react.development.js
72.14 kB | 23.18 kB | 23.70 kB | 8.38 kB | 8.54 kB | 2 | react.development.js

173.90 kB | 59.44 kB | 59.82 kB | 19.16 kB | 19.33 kB | 2 | moment.js
173.90 kB | 59.40 kB | 59.82 kB | 19.16 kB | 19.33 kB | 2 | moment.js

287.63 kB | 89.26 kB | 90.07 kB | 30.91 kB | 31.95 kB | 2 | jquery.js

342.15 kB | 117 kB | 118.14 kB | 43.19 kB | 44.37 kB | 2 | vue.js
342.15 kB | 116.97 kB | 118.14 kB | 43.15 kB | 44.37 kB | 2 | vue.js

544.10 kB | 71.15 kB | 72.48 kB | 25.85 kB | 26.20 kB | 2 | lodash.js
544.10 kB | 71.03 kB | 72.48 kB | 25.76 kB | 26.20 kB | 2 | lodash.js

555.77 kB | 267.45 kB | 270.13 kB | 88.05 kB | 90.80 kB | 2 | d3.js
555.77 kB | 267.39 kB | 270.13 kB | 88.02 kB | 90.80 kB | 2 | d3.js

1.01 MB | 439.53 kB | 458.89 kB | 122.13 kB | 126.71 kB | 2 | bundle.min.js
1.01 MB | 439.40 kB | 458.89 kB | 122.06 kB | 126.71 kB | 2 | bundle.min.js

1.25 MB | 642.77 kB | 646.76 kB | 159.40 kB | 163.73 kB | 2 | three.js
1.25 MB | 642.65 kB | 646.76 kB | 159.38 kB | 163.73 kB | 2 | three.js

2.14 MB | 712.11 kB | 724.14 kB | 160.89 kB | 181.07 kB | 2 | victory.js
2.14 MB | 711.11 kB | 724.14 kB | 160.41 kB | 181.07 kB | 2 | victory.js

3.20 MB | 1.00 MB | 1.01 MB | 323.05 kB | 331.56 kB | 3 | echarts.js
3.20 MB | 1.00 MB | 1.01 MB | 322.51 kB | 331.56 kB | 3 | echarts.js

6.69 MB | 2.22 MB | 2.31 MB | 458.81 kB | 488.28 kB | 4 | antd.js
6.69 MB | 2.22 MB | 2.31 MB | 458.38 kB | 488.28 kB | 4 | antd.js

10.95 MB | 3.34 MB | 3.49 MB | 855.09 kB | 915.50 kB | 4 | typescript.js
10.95 MB | 3.33 MB | 3.49 MB | 853.27 kB | 915.50 kB | 4 | typescript.js

10 changes: 5 additions & 5 deletions tasks/track_memory_allocations/allocs_minifier.snap
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs | Arena bytes
-------------------------------------------------------------------------------------------------------------------------------------------
checker.ts | 2.92 MB || 84078 | 14191 || 153771 | 29399
checker.ts | 2.92 MB || 83481 | 14179 || 152610 | 28185

cal.com.tsx | 1.06 MB || 40528 | 3033 || 37173 | 4736
cal.com.tsx | 1.06 MB || 40446 | 3033 || 37151 | 4578

RadixUIAdoptionSection.jsx | 2.52 kB || 85 | 9 || 30 | 6

pdf.mjs | 567.30 kB || 19825 | 2900 || 47465 | 7754
pdf.mjs | 567.30 kB || 19808 | 2899 || 47442 | 7725

antd.js | 6.69 MB || 99749 | 13523 || 331957 | 69885
antd.js | 6.69 MB || 99498 | 13523 || 331565 | 69251

binder.ts | 193.08 kB || 4771 | 974 || 7059 | 834
binder.ts | 193.08 kB || 4760 | 974 || 7075 | 824

Loading