Skip to content

Commit 0817970

Browse files
authored
feat(es/minifier): Remove needless blocks (#10234)
**Description:** I postponed this while working on `dead_branch_remover` removal PR.
1 parent 6841523 commit 0817970

File tree

54 files changed

+1489
-1568
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1489
-1568
lines changed

Diff for: crates/swc/tests/fixture/issues-4xxx/4841/output/index.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
global._processChunk = function r(r, c, i) {
22
if (r) {
3-
if (!c) {
4-
return true;
5-
}
3+
if (!c) return true;
64
var i = this.write();
75
return (i.callback = callback), void 0;
86
}

Diff for: crates/swc/tests/libs-size.snapshot.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
| File | Original Size | Compressed Size | Gzipped Size |
22
| --- | --- | --- | --- |
3-
| antd.js | 6.38 MiB | 2.05 MiB | 444.54 KiB |
3+
| antd.js | 6.38 MiB | 2.05 MiB | 444.51 KiB |
44
| d3.js | 542.74 KiB | 259.02 KiB | 85.06 KiB |
5-
| echarts.js | 3.41 MiB | 971.34 KiB | 313.43 KiB |
6-
| jquery.js | 280.89 KiB | 87.09 KiB | 30.15 KiB |
5+
| echarts.js | 3.41 MiB | 971.32 KiB | 313.35 KiB |
6+
| jquery.js | 280.89 KiB | 87.12 KiB | 30.16 KiB |
77
| lodash.js | 531.35 KiB | 68.18 KiB | 24.52 KiB |
8-
| moment.js | 169.83 KiB | 56.90 KiB | 18.18 KiB |
9-
| react.js | 70.45 KiB | 22.28 KiB | 8.01 KiB |
10-
| terser.js | 1.08 MiB | 444.89 KiB | 120.46 KiB |
11-
| three.js | 1.19 MiB | 628.02 KiB | 154.56 KiB |
12-
| typescript.js | 10.45 MiB | 3.17 MiB | 845.72 KiB |
13-
| victory.js | 2.30 MiB | 689.65 KiB | 153.65 KiB |
14-
| vue.js | 334.13 KiB | 112.97 KiB | 41.66 KiB |
8+
| moment.js | 169.83 KiB | 57.03 KiB | 18.20 KiB |
9+
| react.js | 70.45 KiB | 22.28 KiB | 8.00 KiB |
10+
| terser.js | 1.08 MiB | 444.92 KiB | 120.46 KiB |
11+
| three.js | 1.19 MiB | 628.03 KiB | 154.56 KiB |
12+
| typescript.js | 10.45 MiB | 3.17 MiB | 845.79 KiB |
13+
| victory.js | 2.30 MiB | 689.67 KiB | 153.65 KiB |
14+
| vue.js | 334.13 KiB | 112.95 KiB | 41.68 KiB |

Diff for: crates/swc_ecma_minifier/src/compress/pure/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ impl VisitMut for Pure<'_> {
637637

638638
{
639639
let ctx = Ctx {
640-
preserve_block: true,
640+
preserve_block: false,
641641
..self.ctx
642642
};
643643
s.cons.visit_mut_with(&mut *self.with_ctx(ctx));

Diff for: crates/swc_ecma_minifier/tests/benches-full/echarts.js

+133-135
Large diffs are not rendered by default.

Diff for: crates/swc_ecma_minifier/tests/benches-full/jquery.js

+42-37
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,7 @@
153153
for("boolean" == typeof target && (deep = target, // Skip the boolean and the target
154154
target = arguments[i] || {}, i++), "object" == typeof target || isFunction(target) || (target = {}), i === length && (target = this, i--); i < length; i++)// Only deal with non-null/undefined values
155155
if (null != (options = arguments[i])) // Extend the base object
156-
for(name in options)// Prevent Object.prototype pollution
157-
// Prevent never-ending loop
158-
copy = options[name], "__proto__" !== name && target !== copy && (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy))) ? (src = target[name], clone = copyIsArray && !Array.isArray(src) ? [] : copyIsArray || jQuery.isPlainObject(src) ? src : {}, copyIsArray = !1, // Never move original objects, clone them
156+
for(name in options)copy = options[name], "__proto__" !== name && target !== copy && (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy))) ? (src = target[name], clone = copyIsArray && !Array.isArray(src) ? [] : copyIsArray || jQuery.isPlainObject(src) ? src : {}, copyIsArray = !1, // Never move original objects, clone them
159157
target[name] = jQuery.extend(deep, clone, copy)) : void 0 !== copy && (target[name] = copy));
160158
// Return the modified object
161159
return target;
@@ -334,11 +332,10 @@
334332
{
335333
if (9 === nodeType) {
336334
if (!(elem = context.getElementById(m))) return results;
337-
// Support: IE, Opera, Webkit
335+
else // Support: IE, Opera, Webkit
338336
// TODO: identify versions
339337
// getElementById can match elements by name instead of ID
340338
if (elem.id === m) return results.push(elem), results;
341-
// Element context
342339
} else // Support: IE, Opera, Webkit
343340
// TODO: identify versions
344341
// getElementById can match elements by name instead of ID
@@ -440,16 +437,23 @@
440437
// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
441438
// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
442439
if ("form" in elem) {
443-
return(// Check for inherited disabledness on relevant non-disabled elements:
440+
// Check for inherited disabledness on relevant non-disabled elements:
444441
// * listed form-associated elements in a disabled fieldset
445442
// https://html.spec.whatwg.org/multipage/forms.html#category-listed
446443
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
447444
// * option elements in a disabled optgroup
448445
// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
449446
// All such elements have a "form" property.
450-
elem.parentNode && !1 === elem.disabled ? // Option elements defer to a parent optgroup if present
451-
"label" in elem ? "label" in elem.parentNode ? elem.parentNode.disabled === disabled : elem.disabled === disabled : elem.isDisabled === disabled || // Where there is no isDisabled, check manually
452-
/* jshint -W018 */ !disabled !== elem.isDisabled && inDisabledFieldset(elem) === disabled : elem.disabled === disabled);
447+
if (elem.parentNode && !1 === elem.disabled) {
448+
// Option elements defer to a parent optgroup if present
449+
if ("label" in elem) if ("label" in elem.parentNode) return elem.parentNode.disabled === disabled;
450+
else return elem.disabled === disabled;
451+
// Support: IE 6 - 11
452+
// Use the isDisabled shortcut property to check for disabled fieldset ancestors
453+
return elem.isDisabled === disabled || // Where there is no isDisabled, check manually
454+
/* jshint -W018 */ !disabled !== elem.isDisabled && inDisabledFieldset(elem) === disabled;
455+
}
456+
return elem.disabled === disabled;
453457
// Try to winnow out elements that can't be disabled before trusting the disabled property.
454458
// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
455459
// even exist on them, let alone have a boolean value.
@@ -716,13 +720,12 @@
716720
*/ getText = Sizzle.getText = function(elem) {
717721
var node, ret = "", i = 0, nodeType = elem.nodeType;
718722
if (nodeType) {
719-
if (1 === nodeType || 9 === nodeType || 11 === nodeType) {
720-
// Use textContent for elements
721-
// innerText usage removed for consistency of new lines (jQuery #11153)
722-
if ("string" == typeof elem.textContent) return elem.textContent;
723-
// Traverse its children
724-
for(elem = elem.firstChild; elem; elem = elem.nextSibling)ret += getText(elem);
725-
} else if (3 === nodeType || 4 === nodeType) return elem.nodeValue;
723+
if (1 === nodeType || 9 === nodeType || 11 === nodeType) // Use textContent for elements
724+
// innerText usage removed for consistency of new lines (jQuery #11153)
725+
if ("string" == typeof elem.textContent) return elem.textContent;
726+
else // Traverse its children
727+
for(elem = elem.firstChild; elem; elem = elem.nextSibling)ret += getText(elem);
728+
else if (3 === nodeType || 4 === nodeType) return elem.nodeValue;
726729
} else // If no nodeType, this is expected to be an array
727730
for(; node = elem[i++];)// Do not traverse comment nodes
728731
ret += getText(node);
@@ -1045,13 +1048,13 @@
10451048
// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
10461049
if (xml) {
10471050
for(; elem = elem[dir];)if ((1 === elem.nodeType || checkNonElements) && matcher(elem, context, xml)) return !0;
1048-
} else for(; elem = elem[dir];)if (1 === elem.nodeType || checkNonElements) {
1049-
if (// Support: IE <9 only
1050-
// Defend against cloned attroperties (jQuery gh-1709)
1051-
uniqueCache = (outerCache = elem[expando] || (elem[expando] = {}))[elem.uniqueID] || (outerCache[elem.uniqueID] = {}), skip && skip === elem.nodeName.toLowerCase()) elem = elem[dir] || elem;
1052-
else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) // Assign to newCache so results back-propagate to previous elements
1051+
} else for(; elem = elem[dir];)if (1 === elem.nodeType || checkNonElements) if (// Support: IE <9 only
1052+
// Defend against cloned attroperties (jQuery gh-1709)
1053+
uniqueCache = (outerCache = elem[expando] || (elem[expando] = {}))[elem.uniqueID] || (outerCache[elem.uniqueID] = {}), skip && skip === elem.nodeName.toLowerCase()) elem = elem[dir] || elem;
1054+
else {
1055+
if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) // Assign to newCache so results back-propagate to previous elements
10531056
return newCache[2] = oldCache[2];
1054-
else // A match means we're done; a fail means we have to keep checking
1057+
// A match means we're done; a fail means we have to keep checking
10551058
if (// Reuse newcache so results back-propagate to previous elements
10561059
uniqueCache[key] = newCache, newCache[2] = matcher(elem, context, xml)) return !0;
10571060
}
@@ -1329,17 +1332,17 @@
13291332
null,
13301333
selector,
13311334
null
1332-
] : rquickExpr.exec(selector)) && (match[1] || !context)) {
1333-
// HANDLE: $(html) -> $(array)
1334-
if (!match[1]) return (elem = document.getElementById(match[2])) && (// Inject the element directly into the jQuery object
1335-
this[0] = elem, this.length = 1), this;
1335+
] : rquickExpr.exec(selector)) && (match[1] || !context)) // HANDLE: $(html) -> $(array)
1336+
if (!match[1]) return (elem = document.getElementById(match[2])) && (// Inject the element directly into the jQuery object
1337+
this[0] = elem, this.length = 1), this;
1338+
else {
13361339
// HANDLE: $(html, props)
13371340
if (context = context instanceof jQuery ? context[0] : context, // Option to run scripts is true for back-compat
13381341
// Intentionally let the error be thrown if parseHTML is not present
13391342
jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, !0)), rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) for(match in context)// Properties of context are called as methods if possible
13401343
isFunction(this[match]) ? this[match](context[match]) : this.attr(match, context[match]);
13411344
return this;
1342-
// HANDLE: $(expr, $(...))
1345+
// HANDLE: $(#id)
13431346
}
13441347
return !context || context.jquery ? (context || root).find(selector) : this.constructor(context).find(selector);
13451348
// HANDLE: $(DOMElement)
@@ -3164,12 +3167,10 @@
31643167
hooks.unqueued--, jQuery.queue(elem, "fx").length || hooks.empty.fire();
31653168
});
31663169
})), props)if (value = props[prop], rfxtypes.test(value)) {
3167-
if (delete props[prop], toggle = toggle || "toggle" === value, value === (hidden ? "hide" : "show")) {
3168-
// Pretend to be hidden if this is a "show" and
3169-
// there is still data from a stopped show/hide
3170-
if ("show" !== value || !dataShow || void 0 === dataShow[prop]) continue;
3171-
hidden = !0;
3172-
}
3170+
if (delete props[prop], toggle = toggle || "toggle" === value, value === (hidden ? "hide" : "show")) // Pretend to be hidden if this is a "show" and
3171+
// there is still data from a stopped show/hide
3172+
if ("show" !== value || !dataShow || void 0 === dataShow[prop]) continue;
3173+
else hidden = !0;
31733174
orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
31743175
}
31753176
if (!(!// Bail out if this is a no-op like .hide().hide()
@@ -3505,7 +3506,7 @@
35053506
var hooks, ret, valueIsFunction, elem = this[0];
35063507
return arguments.length ? (valueIsFunction = isFunction(value), this.each(function(i) {
35073508
var val;
3508-
1 === this.nodeType && (null == (val = valueIsFunction ? value.call(this, i, jQuery(this).val()) : value) ? val = "" : "number" == typeof val ? val += "" : Array.isArray(val) && (val = jQuery.map(val, function(value) {
3509+
1 !== this.nodeType || (null == (val = valueIsFunction ? value.call(this, i, jQuery(this).val()) : value) ? val = "" : "number" == typeof val ? val += "" : Array.isArray(val) && (val = jQuery.map(val, function(value) {
35093510
return null == value ? "" : value + "";
35103511
})), (hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]) && "set" in hooks && void 0 !== hooks.set(this, val, "value") || (this.value = val));
35113512
})) : elem ? (hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()]) && "get" in hooks && void 0 !== (ret = hooks.get(elem, "value")) ? ret : "string" == typeof (ret = elem.value) ? ret.replace(rreturn, "") : null == ret ? "" : ret : void 0;
@@ -3956,7 +3957,7 @@
39563957
function done(status, nativeStatusText, responses, headers) {
39573958
var isSuccess, success, error, response, modified, statusText = nativeStatusText;
39583959
// Ignore repeat invocations
3959-
!completed && (completed = !0, timeoutTimer && window1.clearTimeout(timeoutTimer), // Dereference transport for early garbage collection
3960+
completed || (completed = !0, timeoutTimer && window1.clearTimeout(timeoutTimer), // Dereference transport for early garbage collection
39603961
// (no matter how long the jqXHR object will be used)
39613962
transport = void 0, // Cache response headers
39623963
responseHeadersString = headers || "", // Set readyState
@@ -4327,14 +4328,18 @@
43274328
jQuery.offset.setOffset(this, options, i);
43284329
});
43294330
var rect, win, elem = this[0];
4330-
return elem ? elem.getClientRects().length ? (// Get document-relative position by adding viewport scroll to viewport-relative gBCR
4331+
if (elem) return(// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
4332+
// Support: IE <=11 only
4333+
// Running getBoundingClientRect on a
4334+
// disconnected node in IE throws an error
4335+
elem.getClientRects().length ? (// Get document-relative position by adding viewport scroll to viewport-relative gBCR
43314336
rect = elem.getBoundingClientRect(), win = elem.ownerDocument.defaultView, {
43324337
top: rect.top + win.pageYOffset,
43334338
left: rect.left + win.pageXOffset
43344339
}) : {
43354340
top: 0,
43364341
left: 0
4337-
} : void 0;
4342+
});
43384343
},
43394344
// position() relates an element's margin box to its offset parent's padding box
43404345
// This corresponds to the behavior of CSS absolute positioning

Diff for: crates/swc_ecma_minifier/tests/benches-full/lodash.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -10673,10 +10673,8 @@
1067310673
for(var iterIndex = -1, value = array[index += dir]; ++iterIndex < iterLength;){
1067410674
var data = iteratees[iterIndex], iteratee = data.iteratee, type = data.type, computed = iteratee(value);
1067510675
if (2 == type) value = computed;
10676-
else if (!computed) {
10677-
if (1 == type) continue outer;
10678-
break outer;
10679-
}
10676+
else if (!computed) if (1 == type) continue outer;
10677+
else break outer;
1068010678
}
1068110679
result[resIndex++] = value;
1068210680
}

0 commit comments

Comments
 (0)