Skip to content

Commit

Permalink
feat(html/minifier): Remove empty script and style tags with attribut…
Browse files Browse the repository at this point in the history
…es (#6447)
  • Loading branch information
alexander-akait committed Nov 17, 2022
1 parent 95d274e commit 7441721
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 18 deletions.
58 changes: 43 additions & 15 deletions crates/swc_html_minifier/src/lib.rs
Expand Up @@ -608,6 +608,12 @@ impl Minifier<'_> {
}
}

fn is_type_text_css(&self, value: &JsWord) -> bool {
let value = value.trim().to_ascii_lowercase();

matches!(&*value, "text/css")
}

fn is_default_attribute_value(&self, element: &Element, attribute: &Attribute) -> bool {
let attribute_value = match &attribute.value {
Some(value) => value,
Expand Down Expand Up @@ -652,7 +658,7 @@ impl Minifier<'_> {
},
js_word!("link") => {
if attribute.name == js_word!("type")
&& &*attribute_value.trim().to_ascii_lowercase() == "text/css"
&& self.is_type_text_css(attribute_value)
{
return true;
}
Expand Down Expand Up @@ -1305,9 +1311,38 @@ impl Minifier<'_> {

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

if element.attributes.len() == 1 {
return element.attributes.iter().all(|attr| {
attr.name == js_word!("type")
&& attr.value.is_some()
&& self.is_type_text_css(attr.value.as_ref().unwrap())
});
}
} else if matches!(element.namespace, Namespace::HTML | Namespace::SVG)
&& element.tag_name == js_word!("script")
&& self.is_empty_children(&element.children)
{
if element.attributes.is_empty() {
return true;
}

if element.attributes.len() == 1 {
return element.attributes.iter().all(|attr| {
attr.name == js_word!("type")
&& attr.value.is_some()
&& (attr.value == Some(js_word!("module"))
|| self.is_type_text_javascript(attr.value.as_ref().unwrap()))
});
}
} else if (!self.is_element_displayed(element)
|| (element.namespace == Namespace::HTML
&& element.tag_name == js_word!("noscript")))
&& element.attributes.is_empty()
Expand Down Expand Up @@ -1360,7 +1395,7 @@ impl Minifier<'_> {
}
js_word!("type") => {
if let Some(value) = &attribute.value {
if (is_style_tag && value.trim().to_ascii_lowercase() == "text/css")
if (is_style_tag && self.is_type_text_css(value))
|| (is_script_tag && self.is_type_text_javascript(value))
{
false
Expand Down Expand Up @@ -1402,7 +1437,7 @@ impl Minifier<'_> {
}
js_word!("type") => {
if let Some(value) = &attribute.value {
if (is_style_tag && value.trim().to_ascii_lowercase() == "text/css")
if (is_style_tag && self.is_type_text_css(value))
|| (is_script_tag && self.is_type_text_javascript(value))
{
false
Expand Down Expand Up @@ -3005,21 +3040,14 @@ impl VisitMut for Minifier<'_> {

for attribute in &current_element.attributes {
if attribute.name == js_word!("type") && attribute.value.is_some() {
type_attribute_value = Some(
attribute
.value
.as_ref()
.unwrap()
.trim()
.to_ascii_lowercase(),
);
type_attribute_value = Some(attribute.value.as_ref().unwrap());

break;
}
}

if type_attribute_value.is_none()
|| type_attribute_value == Some("text/css".into())
|| self.is_type_text_css(type_attribute_value.as_ref().unwrap())
{
text_type = Some(MinifierType::Css)
}
Expand Down
Expand Up @@ -19,5 +19,21 @@


</script>
<script type="module"></script>
<span>Empty modules</span>
<script type="module">



</script>
<script type="text/javascript"></script>
<span>Empty scripts</span>
<script type="text/javascript">



</script>
<span>Empty styles</span>
<style type="text/css"></style>
</body>
</html>
@@ -1,4 +1,8 @@
<!doctype html><html lang=en><svg>


</svg>
</svg>
<span>Empty modules</span>
<span>Empty scripts</span>

<span>Empty styles</span>
Expand Up @@ -223,5 +223,29 @@
<script type="module"></script>
<script type="module"></script>

<script type="module"></script>
<script type="module"></script>

<div>breaker</div>
<script type="module">

</script>
<script type="module">

</script>

<div>breaker</div>
<script type="text/javascript"></script>
<script type="application/javascript"></script>

<div>breaker</div>
<script type="text/javascript">

</script>
<script type="application/javascript">

</script>


</body>
</html>
Expand Up @@ -97,5 +97,16 @@


<div>breaker</div>
<script type=module></script>
<script type=module></script>






<div>breaker</div>

<div>breaker</div>



<div>breaker</div>

1 comment on commit 7441721

@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: 7441721 Previous: dabea71 Ratio
es/full/bugs-1 336386 ns/iter (± 16008) 380309 ns/iter (± 29903) 0.88
es/full/minify/libraries/antd 1829925137 ns/iter (± 19703431) 2137349110 ns/iter (± 101724270) 0.86
es/full/minify/libraries/d3 394936502 ns/iter (± 14038189) 494321806 ns/iter (± 33766541) 0.80
es/full/minify/libraries/echarts 1597043020 ns/iter (± 32949043) 1715818213 ns/iter (± 152348982) 0.93
es/full/minify/libraries/jquery 112455796 ns/iter (± 3168567) 126117900 ns/iter (± 9372918) 0.89
es/full/minify/libraries/lodash 132469716 ns/iter (± 4546946) 146710926 ns/iter (± 10546392) 0.90
es/full/minify/libraries/moment 62608562 ns/iter (± 3260619) 74247392 ns/iter (± 11578709) 0.84
es/full/minify/libraries/react 22530641 ns/iter (± 1009319) 23028002 ns/iter (± 954786) 0.98
es/full/minify/libraries/terser 313290319 ns/iter (± 4965725) 374635589 ns/iter (± 21170901) 0.84
es/full/minify/libraries/three 565116172 ns/iter (± 15612929) 633513788 ns/iter (± 60603354) 0.89
es/full/minify/libraries/typescript 3353129683 ns/iter (± 25602673) 3877807461 ns/iter (± 139431744) 0.86
es/full/minify/libraries/victory 820400434 ns/iter (± 11924354) 964824116 ns/iter (± 92271028) 0.85
es/full/minify/libraries/vue 151618721 ns/iter (± 6198946) 270336575 ns/iter (± 45107603) 0.56
es/full/codegen/es3 33564 ns/iter (± 533) 50595 ns/iter (± 18831) 0.66
es/full/codegen/es5 33552 ns/iter (± 322) 44381 ns/iter (± 19426) 0.76
es/full/codegen/es2015 33492 ns/iter (± 591) 44668 ns/iter (± 7161) 0.75
es/full/codegen/es2016 33532 ns/iter (± 765) 41311 ns/iter (± 6554) 0.81
es/full/codegen/es2017 33529 ns/iter (± 1367) 42148 ns/iter (± 7319) 0.80
es/full/codegen/es2018 33053 ns/iter (± 979) 43863 ns/iter (± 7645) 0.75
es/full/codegen/es2019 33213 ns/iter (± 577) 43638 ns/iter (± 7072) 0.76
es/full/codegen/es2020 32598 ns/iter (± 1170) 46075 ns/iter (± 9642) 0.71
es/full/all/es3 189891800 ns/iter (± 5512388) 274822916 ns/iter (± 67020098) 0.69
es/full/all/es5 179208144 ns/iter (± 5100538) 260793154 ns/iter (± 42808549) 0.69
es/full/all/es2015 143821154 ns/iter (± 4045032) 204560709 ns/iter (± 25521892) 0.70
es/full/all/es2016 142141554 ns/iter (± 4979353) 201088334 ns/iter (± 22089485) 0.71
es/full/all/es2017 142283418 ns/iter (± 5250951) 196993358 ns/iter (± 31906276) 0.72
es/full/all/es2018 140380853 ns/iter (± 4125286) 196914836 ns/iter (± 28295749) 0.71
es/full/all/es2019 139195315 ns/iter (± 3421829) 197096392 ns/iter (± 19374217) 0.71
es/full/all/es2020 133959142 ns/iter (± 3532239) 187010122 ns/iter (± 32728069) 0.72
es/full/parser 721884 ns/iter (± 49747) 903626 ns/iter (± 151374) 0.80
es/full/base/fixer 26238 ns/iter (± 1030) 29721 ns/iter (± 3373) 0.88
es/full/base/resolver_and_hygiene 91058 ns/iter (± 4382) 123733 ns/iter (± 36128) 0.74
serialization of ast node 217 ns/iter (± 2) 266 ns/iter (± 44) 0.82
serialization of serde 221 ns/iter (± 3) 281 ns/iter (± 44) 0.79

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

Please sign in to comment.