Skip to content

Commit

Permalink
fix(html/minifier): Fix bugs of merging and removing metadata elements (
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Oct 19, 2022
1 parent dc2c416 commit 3546632
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 18 deletions.
65 changes: 48 additions & 17 deletions crates/swc_html_minifier/src/lib.rs
Expand Up @@ -1204,7 +1204,25 @@ impl Minifier<'_> {
None
}

fn empty_children(&self, children: &Vec<Child>) -> bool {
fn is_empty_metadata_element(&self, child: &Child) -> bool {
if let Child::Element(element) = child {
if (!self.is_element_displayed(element.namespace, &element.tag_name)
|| (matches!(element.namespace, Namespace::HTML | Namespace::SVG)
&& element.tag_name == js_word!("script"))
|| (element.namespace == Namespace::HTML
&& element.tag_name == js_word!("noscript")))
&& element.attributes.is_empty()
&& self.is_empty_children(&element.children)
&& element.content.is_none()
{
return true;
}
}

false
}

fn is_empty_children(&self, children: &Vec<Child>) -> bool {
for child in children {
match child {
Child::Text(text) if text.data.chars().all(is_whitespace) => {
Expand Down Expand Up @@ -1251,6 +1269,10 @@ impl Minifier<'_> {
}

fn minify_children(&mut self, children: &mut Vec<Child>) -> Vec<Child> {
if children.is_empty() {
return vec![];
}

let (namespace, tag_name) = match &self.current_element {
Some(element) => (element.namespace, &element.tag_name),
_ => {
Expand All @@ -1266,22 +1288,6 @@ impl Minifier<'_> {
Child::Comment(comment) if self.options.remove_comments => {
self.is_preserved_comment(&comment.data)
}
Child::Element(element)
if self.options.remove_empty_metadata_elements
&& (!self
.is_element_displayed(element.namespace, &element.tag_name)
|| (matches!(
element.namespace,
Namespace::HTML | Namespace::SVG
) && element.tag_name == js_word!("script"))
|| (element.namespace == Namespace::HTML
&& element.tag_name == js_word!("noscript")))
&& element.attributes.is_empty()
&& self.empty_children(&element.children)
&& element.content.is_none() =>
{
false
}
Child::Element(element)
if self.options.merge_metadata_elements
&& self.allow_elements_to_merge(prev_children.last(), element) =>
Expand Down Expand Up @@ -1601,6 +1607,31 @@ impl Minifier<'_> {
let result = child_will_be_retained(&mut child, &mut new_children, children);

if result {
if self.options.remove_redundant_attributes
&& self.is_empty_metadata_element(&child)
{
let need_continue = {
let next_element = if let Some(Child::Element(element)) = children.get(0) {
Some(element)
} else if let Some(Child::Element(element)) = children.get(1) {
Some(element)
} else {
None
};

if let Some(element) = next_element {
self.options.merge_metadata_elements
&& !self.allow_elements_to_merge(Some(&child), element)
} else {
true
}
};

if need_continue {
continue;
}
}

new_children.push(child);
}
}
Expand Down
@@ -0,0 +1,4 @@
{
"mergeMetadataElements": false,
"removeEmptyMetadataElements": false
}
@@ -0,0 +1,64 @@
<!doctype html>
<html lang="en">
<head>
<title>Document</title>
<style>
a {
color:red
}
</style><style>
b {
color:blue
}
</style>
<!-- test -->
<style>
p {
color: white;
background-color: blue;
padding: 5px;
border: 1px solid black;
}
</style>
<style>
p {
color: blue;
background-color: yellow;
}
</style>
<style media="all and (max-width: 500px)">
p {
color: blue;
background-color: yellow;
}
</style>
<style type="text/css">
.first {
color: red;
}
</style>
<style type="text/css">
.second {
color: red;
}
</style>
<style media="all">
p {
color: blue;
}
</style>
<style media="all">
p {
color: red;
}
</style>
</head>
<body>
<div>test</div>
<style>a { color: red }</style>
<style></style>
<div>test</div>
<style></style>
<style>a { color: red }</style>
</body>
</html>
@@ -0,0 +1,4 @@
<!doctype html><html lang=en><title>Document</title><style>a{color:red}</style><style>b{color:blue}</style><style>p{color:white;background-color:blue;padding:5px;border:1px solid black}</style><style>p{color:blue;background-color:yellow}</style><style media="all and (max-width:500px)">p{color:blue;background-color:yellow}</style><style>.first{color:red}</style><style>.second{color:red}</style><style media=all>p{color:blue}</style><style media=all>p{color:red}</style><div>test</div>
<style>a{color:red}</style><style></style>
<div>test</div>
<style></style><style>a{color:red}</style>
Expand Up @@ -4,5 +4,4 @@
<div>test</div>
<style>a{color:red}</style>
<div>test</div>

<style>a{color:red}</style>

1 comment on commit 3546632

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 3546632 Previous: ac7cfa1 Ratio
es/full/minify/libraries/antd 1849917683 ns/iter (± 47011429) 1936211939 ns/iter (± 84626124) 0.96
es/full/minify/libraries/d3 387977118 ns/iter (± 15675250) 407642390 ns/iter (± 23512584) 0.95
es/full/minify/libraries/echarts 1528868284 ns/iter (± 69666641) 1575935113 ns/iter (± 51718197) 0.97
es/full/minify/libraries/jquery 103306798 ns/iter (± 6055879) 114110115 ns/iter (± 4748088) 0.91
es/full/minify/libraries/lodash 115854563 ns/iter (± 6276858) 118953556 ns/iter (± 7356986) 0.97
es/full/minify/libraries/moment 64928146 ns/iter (± 4091272) 63147471 ns/iter (± 11386188) 1.03
es/full/minify/libraries/react 20943470 ns/iter (± 1033868) 19766423 ns/iter (± 418342) 1.06
es/full/minify/libraries/terser 329252558 ns/iter (± 15074390) 317328741 ns/iter (± 10994451) 1.04
es/full/minify/libraries/three 556533983 ns/iter (± 19212745) 555009274 ns/iter (± 16838877) 1.00
es/full/minify/libraries/typescript 3349976972 ns/iter (± 36449791) 3351725271 ns/iter (± 54038362) 1.00
es/full/minify/libraries/victory 790774235 ns/iter (± 15148403) 793090127 ns/iter (± 12092898) 1.00
es/full/minify/libraries/vue 137847061 ns/iter (± 2797599) 140598366 ns/iter (± 3999963) 0.98
es/full/codegen/es3 33512 ns/iter (± 856) 32909 ns/iter (± 917) 1.02
es/full/codegen/es5 33642 ns/iter (± 365) 32882 ns/iter (± 1775) 1.02
es/full/codegen/es2015 33616 ns/iter (± 738) 33053 ns/iter (± 1068) 1.02
es/full/codegen/es2016 33606 ns/iter (± 372) 33044 ns/iter (± 742) 1.02
es/full/codegen/es2017 33577 ns/iter (± 619) 32941 ns/iter (± 387) 1.02
es/full/codegen/es2018 33448 ns/iter (± 1081) 33250 ns/iter (± 1001) 1.01
es/full/codegen/es2019 33287 ns/iter (± 1337) 33451 ns/iter (± 770) 1.00
es/full/codegen/es2020 33537 ns/iter (± 1927) 33471 ns/iter (± 1632) 1.00
es/full/all/es3 195932333 ns/iter (± 12192370) 189949137 ns/iter (± 7198156) 1.03
es/full/all/es5 194670157 ns/iter (± 14681394) 180394514 ns/iter (± 4943662) 1.08
es/full/all/es2015 160191742 ns/iter (± 13158160) 144251831 ns/iter (± 6262216) 1.11
es/full/all/es2016 143206486 ns/iter (± 6330463) 145473955 ns/iter (± 7923568) 0.98
es/full/all/es2017 147262853 ns/iter (± 11797597) 144483319 ns/iter (± 4246513) 1.02
es/full/all/es2018 155132294 ns/iter (± 10557820) 140014291 ns/iter (± 5864304) 1.11
es/full/all/es2019 140720254 ns/iter (± 11293203) 140680247 ns/iter (± 5309763) 1.00
es/full/all/es2020 136463664 ns/iter (± 6348042) 134900780 ns/iter (± 2957383) 1.01
es/full/parser 712894 ns/iter (± 19205) 707857 ns/iter (± 55110) 1.01
es/full/base/fixer 26415 ns/iter (± 546) 26676 ns/iter (± 2952) 0.99
es/full/base/resolver_and_hygiene 89639 ns/iter (± 3041) 93061 ns/iter (± 2317) 0.96
serialization of ast node 229 ns/iter (± 8) 218 ns/iter (± 8) 1.05
serialization of serde 228 ns/iter (± 4) 215 ns/iter (± 3) 1.06

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.