Skip to content

Commit

Permalink
feat(minifier): minify string PropertyKey (#8147)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Dec 27, 2024
1 parent 79af100 commit 8fb71f5
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
4 changes: 4 additions & 0 deletions crates/oxc_minifier/src/ast_passes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ impl<'a> Traverse<'a> for LatePeepholeOptimizations {
fn exit_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
self.x4_peephole_substitute_alternate_syntax.exit_call_expression(expr, ctx);
}

fn exit_property_key(&mut self, key: &mut PropertyKey<'a>, ctx: &mut TraverseCtx<'a>) {
self.x4_peephole_substitute_alternate_syntax.exit_property_key(key, ctx);
}
}

// See `createPeepholeOptimizationsPass`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax {
self.in_define_export = false;
}

fn exit_property_key(&mut self, key: &mut PropertyKey<'a>, ctx: &mut TraverseCtx<'a>) {
self.try_compress_property_key(key, ctx);
}

fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
let ctx = Ctx(ctx);

Expand Down Expand Up @@ -687,6 +691,39 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
fn empty_array_literal(ctx: Ctx<'a, 'b>) -> Expression<'a> {
Self::array_literal(ctx.ast.vec(), ctx)
}

// https://github.com/swc-project/swc/blob/4e2dae558f60a9f5c6d2eac860743e6c0b2ec562/crates/swc_ecma_minifier/src/compress/pure/properties.rs
#[allow(clippy::cast_lossless)]
fn try_compress_property_key(&mut self, key: &mut PropertyKey<'a>, ctx: &mut TraverseCtx<'a>) {
use oxc_syntax::identifier::is_identifier_name;
let PropertyKey::StringLiteral(s) = key else { return };
if match ctx.parent() {
Ancestor::ObjectPropertyKey(key) => *key.computed(),
Ancestor::BindingPropertyKey(key) => *key.computed(),
Ancestor::MethodDefinitionKey(key) => *key.computed(),
Ancestor::PropertyDefinitionKey(key) => *key.computed(),
Ancestor::AccessorPropertyKey(key) => *key.computed(),
_ => true,
} {
return;
}
if is_identifier_name(&s.value) {
self.changed = true;
*key = PropertyKey::StaticIdentifier(
ctx.ast.alloc_identifier_name(s.span, s.value.clone()),
);
} else if (!s.value.starts_with('0') && !s.value.starts_with('+')) || s.value.len() <= 1 {
if let Ok(value) = s.value.parse::<u32>() {
self.changed = true;
*key = PropertyKey::NumericLiteral(ctx.ast.alloc_numeric_literal(
s.span,
value as f64,
None,
NumberBase::Decimal,
));
}
}
}
}

/// Port from <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntaxTest.java>
Expand Down Expand Up @@ -1137,4 +1174,10 @@ mod test {
test("typeof foo !== `number`", "typeof foo != 'number'");
test("`number` !== typeof foo", "'number' != typeof foo");
}

#[test]
fn test_object_key() {
test("({ '0': _, 'a': _ })", "({ 0: _, a: _ })");
test_same("({ '1.1': _, '😊': _, 'a.a': _ })");
}
}
18 changes: 9 additions & 9 deletions tasks/minsize/minsize.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ Original | minified | minified | gzip | gzip | Fixture

173.90 kB | 60.22 kB | 59.82 kB | 19.49 kB | 19.33 kB | moment.js

287.63 kB | 90.74 kB | 90.07 kB | 32.21 kB | 31.95 kB | jquery.js
287.63 kB | 90.61 kB | 90.07 kB | 32.19 kB | 31.95 kB | jquery.js

342.15 kB | 118.77 kB | 118.14 kB | 44.54 kB | 44.37 kB | vue.js
342.15 kB | 118.76 kB | 118.14 kB | 44.54 kB | 44.37 kB | vue.js

544.10 kB | 72.53 kB | 72.48 kB | 26.23 kB | 26.20 kB | lodash.js
544.10 kB | 72.05 kB | 72.48 kB | 26.19 kB | 26.20 kB | lodash.js

555.77 kB | 274.26 kB | 270.13 kB | 91.26 kB | 90.80 kB | d3.js
555.77 kB | 274.04 kB | 270.13 kB | 91.20 kB | 90.80 kB | d3.js

1.01 MB | 461.13 kB | 458.89 kB | 126.91 kB | 126.71 kB | bundle.min.js

1.25 MB | 657.23 kB | 646.76 kB | 164.23 kB | 163.73 kB | three.js
1.25 MB | 656.86 kB | 646.76 kB | 164.20 kB | 163.73 kB | three.js

2.14 MB | 735.67 kB | 724.14 kB | 181.09 kB | 181.07 kB | victory.js
2.14 MB | 735.43 kB | 724.14 kB | 181.01 kB | 181.07 kB | victory.js

3.20 MB | 1.01 MB | 1.01 MB | 332.35 kB | 331.56 kB | echarts.js
3.20 MB | 1.01 MB | 1.01 MB | 332.34 kB | 331.56 kB | echarts.js

6.69 MB | 2.38 MB | 2.31 MB | 495.33 kB | 488.28 kB | antd.js
6.69 MB | 2.36 MB | 2.31 MB | 495.04 kB | 488.28 kB | antd.js

10.95 MB | 3.51 MB | 3.49 MB | 910.94 kB | 915.50 kB | typescript.js
10.95 MB | 3.51 MB | 3.49 MB | 910.95 kB | 915.50 kB | typescript.js

0 comments on commit 8fb71f5

Please sign in to comment.