Skip to content

Commit e6b7cee

Browse files
authoredMar 15, 2025··
perf(es/minifier): Do not repeat applying pure minifier on last (#10196)
**Description:** This is mostly waste of time
1 parent ec3ebe7 commit e6b7cee

File tree

16 files changed

+83
-94
lines changed

16 files changed

+83
-94
lines changed
 

‎.changeset/hot-pants-move.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
swc_core: minor
3+
swc_ecma_minifier: minor
4+
---
5+
6+
perf(es/minifier): Do not repeat applying pure minifier on last

‎crates/swc/tests/fixture/issues-8xxx/8119/output/1.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
let a;
2-
let myArr = [];
1+
let a, myArr = [];
32
function foo(arr) {
43
return arr.push('foo'), 'foo';
54
}

‎crates/swc_ecma_minifier/src/compress/pure/if_return.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl Pure<'_> {
109109
match if_stmt {
110110
Stmt::If(mut s) => {
111111
assert_eq!(s.alt, None);
112-
negate(self.expr_ctx, &mut s.test, false, false);
112+
negate(self.expr_ctx, &mut s.test, true, false);
113113

114114
s.cons = if cons.len() == 1 && is_fine_for_if_cons(&cons[0]) {
115115
Box::new(cons.into_iter().next().unwrap())

‎crates/swc_ecma_minifier/src/compress/pure/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -907,8 +907,6 @@ impl VisitMut for Pure<'_> {
907907

908908
self.handle_stmt_likes(items);
909909

910-
items.retain(|s| !matches!(s, Stmt::Empty(..)));
911-
912910
#[cfg(debug_assertions)]
913911
{
914912
items.visit_with(&mut AssertValid);

‎crates/swc_ecma_minifier/src/compress/pure/vars.rs

+23-17
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ pub(super) struct VarWithOutInitCounter {
300300
}
301301

302302
impl Visit for VarWithOutInitCounter {
303-
noop_visit_type!();
303+
noop_visit_type!(fail);
304304

305305
fn visit_arrow_expr(&mut self, _: &ArrowExpr) {}
306306

@@ -368,36 +368,38 @@ pub(super) struct VarMover {
368368
}
369369

370370
impl VisitMut for VarMover {
371-
noop_visit_mut_type!();
371+
noop_visit_mut_type!(fail);
372372

373373
/// Noop
374374
fn visit_mut_arrow_expr(&mut self, _: &mut ArrowExpr) {}
375375

376+
fn visit_mut_block_stmt(&mut self, n: &mut BlockStmt) {
377+
if self.target != VarDeclKind::Var {
378+
// noop
379+
return;
380+
}
381+
382+
n.visit_mut_children_with(self);
383+
}
384+
376385
/// Noop
377386
fn visit_mut_constructor(&mut self, _: &mut Constructor) {}
378387

388+
fn visit_mut_for_head(&mut self, _: &mut ForHead) {}
389+
379390
/// Noop
380391
fn visit_mut_function(&mut self, _: &mut Function) {}
381392

382393
fn visit_mut_getter_prop(&mut self, _: &mut GetterProp) {}
383394

384-
fn visit_mut_setter_prop(&mut self, _: &mut SetterProp) {}
395+
fn visit_mut_module_decl(&mut self, _: &mut ModuleDecl) {}
385396

386397
fn visit_mut_module_item(&mut self, s: &mut ModuleItem) {
387398
if let ModuleItem::Stmt(_) = s {
388399
s.visit_mut_children_with(self);
389400
}
390401
}
391402

392-
fn visit_mut_block_stmt(&mut self, n: &mut BlockStmt) {
393-
if self.target != VarDeclKind::Var {
394-
// noop
395-
return;
396-
}
397-
398-
n.visit_mut_children_with(self);
399-
}
400-
401403
fn visit_mut_opt_var_decl_or_expr(&mut self, n: &mut Option<VarDeclOrExpr>) {
402404
n.visit_mut_children_with(self);
403405

@@ -408,6 +410,8 @@ impl VisitMut for VarMover {
408410
}
409411
}
410412

413+
fn visit_mut_setter_prop(&mut self, _: &mut SetterProp) {}
414+
411415
fn visit_mut_stmt(&mut self, s: &mut Stmt) {
412416
s.visit_mut_children_with(self);
413417

@@ -419,15 +423,19 @@ impl VisitMut for VarMover {
419423
}
420424
}
421425

426+
fn visit_mut_stmts(&mut self, s: &mut Vec<Stmt>) {
427+
s.visit_mut_children_with(self);
428+
429+
s.retain(|s| !matches!(s, Stmt::Empty(..)));
430+
}
431+
422432
fn visit_mut_var_decl(&mut self, v: &mut VarDecl) {
423433
let old = self.var_decl_kind.take();
424434
self.var_decl_kind = Some(v.kind);
425435
v.visit_mut_children_with(self);
426436
self.var_decl_kind = old;
427437
}
428438

429-
fn visit_mut_for_head(&mut self, _: &mut ForHead) {}
430-
431439
fn visit_mut_var_declarators(&mut self, d: &mut Vec<VarDeclarator>) {
432440
d.visit_mut_children_with(self);
433441

@@ -475,8 +483,6 @@ impl VisitMut for VarMover {
475483

476484
*d = new;
477485
}
478-
479-
fn visit_mut_module_decl(&mut self, _: &mut ModuleDecl) {}
480486
}
481487

482488
pub(super) struct VarPrepender {
@@ -486,7 +492,7 @@ pub(super) struct VarPrepender {
486492
}
487493

488494
impl VisitMut for VarPrepender {
489-
noop_visit_mut_type!();
495+
noop_visit_mut_type!(fail);
490496

491497
/// Noop
492498
fn visit_mut_arrow_expr(&mut self, _: &mut ArrowExpr) {}

‎crates/swc_ecma_minifier/src/lib.rs

+10-19
Original file line numberDiff line numberDiff line change
@@ -200,25 +200,16 @@ pub fn optimize(
200200

201201
n.visit_mut_with(&mut postcompress_optimizer(c));
202202

203-
let mut pass = 0;
204-
loop {
205-
pass += 1;
206-
207-
let mut v = pure_optimizer(
208-
c,
209-
marks,
210-
PureOptimizerConfig {
211-
force_str_for_tpl: Minification.force_str_for_tpl(),
212-
enable_join_vars: true,
213-
#[cfg(feature = "debug")]
214-
debug_infinite_loop: false,
215-
},
216-
);
217-
n.visit_mut_with(&mut v);
218-
if !v.changed() || c.passes <= pass {
219-
break;
220-
}
221-
}
203+
n.visit_mut_with(&mut pure_optimizer(
204+
c,
205+
marks,
206+
PureOptimizerConfig {
207+
force_str_for_tpl: Minification.force_str_for_tpl(),
208+
enable_join_vars: true,
209+
#[cfg(feature = "debug")]
210+
debug_infinite_loop: false,
211+
},
212+
));
222213
}
223214

224215
if let Some(ref mut _t) = timings {

‎crates/swc_ecma_minifier/tests/benches-full/d3.js

+4-8
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ function(global, factory) {
274274
}
275275
}
276276
function maxIndex(values, valueof) {
277-
let max;
278-
let maxIndex = -1, index = -1;
277+
let max, maxIndex = -1, index = -1;
279278
if (void 0 === valueof) for (const value of values)++index, null != value && (max < value || void 0 === max && value >= value) && (max = value, maxIndex = index);
280279
else for (let value of values)null != (value = valueof(value, ++index, values)) && (max < value || void 0 === max && value >= value) && (max = value, maxIndex = index);
281280
return maxIndex;
@@ -286,8 +285,7 @@ function(global, factory) {
286285
}(arrays));
287286
}
288287
function minIndex(values, valueof) {
289-
let min;
290-
let minIndex = -1, index = -1;
288+
let min, minIndex = -1, index = -1;
291289
if (void 0 === valueof) for (const value of values)++index, null != value && (min > value || void 0 === min && value >= value) && (min = value, minIndex = index);
292290
else for (let value of values)null != (value = valueof(value, ++index, values)) && (min > value || void 0 === min && value >= value) && (min = value, minIndex = index);
293291
return minIndex;
@@ -10279,8 +10277,7 @@ function(global, factory) {
1027910277
}, exports1.geoTransverseMercatorRaw = transverseMercatorRaw, exports1.gray = function(l, opacity) {
1028010278
return new Lab(l, 0, 0, null == opacity ? 1 : opacity);
1028110279
}, exports1.greatest = function(values, compare = ascending) {
10282-
let max;
10283-
let defined = !1;
10280+
let max, defined = !1;
1028410281
if (1 === compare.length) {
1028510282
let maxValue;
1028610283
for (const element of values){
@@ -10359,8 +10356,7 @@ function(global, factory) {
1035910356
}, exports1.lab = lab, exports1.lch = function(l, c, h, opacity) {
1036010357
return 1 == arguments.length ? hclConvert(l) : new Hcl(h, c, l, null == opacity ? 1 : opacity);
1036110358
}, exports1.least = function(values, compare = ascending) {
10362-
let min;
10363-
let defined = !1;
10359+
let min, defined = !1;
1036410360
if (1 === compare.length) {
1036510361
let minValue;
1036610362
for (const element of values){

‎crates/swc_ecma_minifier/tests/benches-full/echarts.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -35161,7 +35161,7 @@
3516135161
if (renderLabelForZeroData || !newNode || newNode.getValue() || // Not render data with value 0
3516235162
(newNode = null), newNode !== virtualRoot && oldNode !== virtualRoot) {
3516335163
if (oldNode && oldNode.piece) newNode ? (// Update
35164-
oldNode.piece.updateData(!1, newNode, seriesModel, ecModel, api), data.setItemGraphicEl(newNode.dataIndex, oldNode.piece)) : !!oldNode && oldNode.piece && (group.remove(oldNode.piece), oldNode.piece = null);
35164+
oldNode.piece.updateData(!1, newNode, seriesModel, ecModel, api), data.setItemGraphicEl(newNode.dataIndex, oldNode.piece)) : oldNode && oldNode.piece && (group.remove(oldNode.piece), oldNode.piece = null);
3516535165
else if (newNode) {
3516635166
// Add
3516735167
var piece = new SunburstPiece(newNode, seriesModel, ecModel, api);

‎crates/swc_ecma_minifier/tests/benches-full/victory.js

+4-8
Original file line numberDiff line numberDiff line change
@@ -28540,8 +28540,7 @@
2854028540
});
2854128541
/* harmony import */ var _ascending_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ascending.js */ "../../victory-histogram/node_modules/d3-array/src/ascending.js");
2854228542
function greatest(values, compare = _ascending_js__WEBPACK_IMPORTED_MODULE_0__.default) {
28543-
let max;
28544-
let defined = !1;
28543+
let max, defined = !1;
2854528544
if (1 === compare.length) {
2854628545
let maxValue;
2854728546
for (const element of values){
@@ -28801,8 +28800,7 @@
2880128800
});
2880228801
/* harmony import */ var _ascending_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ascending.js */ "../../victory-histogram/node_modules/d3-array/src/ascending.js");
2880328802
function least(values, compare = _ascending_js__WEBPACK_IMPORTED_MODULE_0__.default) {
28804-
let min;
28805-
let defined = !1;
28803+
let min, defined = !1;
2880628804
if (1 === compare.length) {
2880728805
let minValue;
2880828806
for (const element of values){
@@ -28851,8 +28849,7 @@
2885128849
\************************************************************************************************************/ /*! exports provided: default */ /***/ function(module1, __webpack_exports__, __webpack_require__) {
2885228850
"use strict";
2885328851
function maxIndex(values, valueof) {
28854-
let max;
28855-
let maxIndex = -1, index = -1;
28852+
let max, maxIndex = -1, index = -1;
2885628853
if (void 0 === valueof) for (const value of values)++index, null != value && (max < value || void 0 === max && value >= value) && (max = value, maxIndex = index);
2885728854
else for (let value of values)null != (value = valueof(value, ++index, values)) && (max < value || void 0 === max && value >= value) && (max = value, maxIndex = index);
2885828855
return maxIndex;
@@ -28923,8 +28920,7 @@
2892328920
\************************************************************************************************************/ /*! exports provided: default */ /***/ function(module1, __webpack_exports__, __webpack_require__) {
2892428921
"use strict";
2892528922
function minIndex(values, valueof) {
28926-
let min;
28927-
let minIndex = -1, index = -1;
28923+
let min, minIndex = -1, index = -1;
2892828924
if (void 0 === valueof) for (const value of values)++index, null != value && (min > value || void 0 === min && value >= value) && (min = value, minIndex = index);
2892928925
else for (let value of values)null != (value = valueof(value, ++index, values)) && (min > value || void 0 === min && value >= value) && (min = value, minIndex = index);
2893028926
return minIndex;

‎crates/swc_ecma_minifier/tests/benches-full/vue.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4330,7 +4330,7 @@
43304330
}
43314331
}), root;
43324332
}(template.trim(), options);
4333-
!1 !== options.optimize && ast && (isStaticKey = genStaticKeysCached(options.staticKeys || ''), isPlatformReservedTag = options.isReservedTag || no, // first pass: mark all non-static nodes.
4333+
!1 === options.optimize || ast && (isStaticKey = genStaticKeysCached(options.staticKeys || ''), isPlatformReservedTag = options.isReservedTag || no, // first pass: mark all non-static nodes.
43344334
function markStatic$1(node) {
43354335
if (node.static = 2 !== node.type && (3 === node.type || !!(node.pre || !node.hasBindings && // no dynamic bindings
43364336
!node.if && !node.for && // not v-if or v-for or v-else

‎crates/swc_ecma_minifier/tests/fixture/next/31077/static/chunks/1606726a.10299989c08cb523/output.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1219,8 +1219,8 @@
12191219
// contentEditable.
12201220
ViewTreeUpdater.prototype.addTextblockHacks = function() {
12211221
for(var lastChild = this.top.children[this.index - 1]; lastChild instanceof MarkViewDesc;)lastChild = lastChild.children[lastChild.children.length - 1];
1222-
!(!lastChild || // Empty textblock
1223-
!(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text)) || ((result.safari || result.chrome) && lastChild && "false" == lastChild.dom.contentEditable && this.addHackNode("IMG"), this.addHackNode("BR"));
1222+
(!lastChild || // Empty textblock
1223+
!(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text)) && ((result.safari || result.chrome) && lastChild && "false" == lastChild.dom.contentEditable && this.addHackNode("IMG"), this.addHackNode("BR"));
12241224
}, ViewTreeUpdater.prototype.addHackNode = function(nodeName) {
12251225
if (this.index < this.top.children.length && this.top.children[this.index].matchesHack(nodeName)) this.index++;
12261226
else {

‎crates/swc_ecma_minifier/tests/fixture/next/target-es2015/static/chunks/main-04b5934c26266542/output.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1701,8 +1701,7 @@
17011701
};
17021702
}
17031703
function resolveHref(router, href, resolveAs) {
1704-
let base;
1705-
let urlAsString = "string" == typeof href ? href : _formatUrl.formatWithValidation(href);
1704+
let base, urlAsString = "string" == typeof href ? href : _formatUrl.formatWithValidation(href);
17061705
// repeated slashes and backslashes in the URL are considered
17071706
// invalid and will never match a Next.js page/file
17081707
const urlProtoMatch = urlAsString.match(/^[a-zA-Z]{1,}:\/\//), urlAsStringNoProto = urlProtoMatch ? urlAsString.slice(urlProtoMatch[0].length) : urlAsString;

0 commit comments

Comments
 (0)