Skip to content

Commit

Permalink
feat(html/minifier): Compress default attributes for svg (#5150)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Jul 9, 2022
1 parent 4b48f3f commit 8bc9a40
Show file tree
Hide file tree
Showing 3 changed files with 415 additions and 1 deletion.
191 changes: 191 additions & 0 deletions crates/swc_html_minifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,197 @@ impl Minifier {
"referrerpolicy",
"strict-origin-when-cross-origin"
)
| (Namespace::SVG, "a", "opacity", "1")
| (Namespace::SVG, "altGlyph", "opacity", "1")
| (Namespace::SVG, "altGlyph", "fill", "black")
| (Namespace::SVG, "altGlyph", "fill-opacity", "1")
| (Namespace::SVG, "altGlyph", "fill-rule", "nonzero")
| (Namespace::SVG, "altGlyph", "font-size", "medium")
| (Namespace::SVG, "altGlyph", "font-size-adjust", "none")
| (Namespace::SVG, "altGlyph", "font-stretch", "normal")
| (Namespace::SVG, "altGlyph", "font-style", "normal")
| (Namespace::SVG, "altGlyph", "font-variant", "normal")
| (Namespace::SVG, "altGlyph", "font-weight", "normal")
| (Namespace::SVG, "animate", "begin", "0s")
| (Namespace::SVG, "animate", "dur", "indefinite")
| (Namespace::SVG, "animate", "min", "0")
| (Namespace::SVG, "animate", "opacity", "1")
| (Namespace::SVG, "animate", "rotate", "0")
| (Namespace::SVG, "animate", "restart", "always")
| (Namespace::SVG, "animate", "fill", "remove")
| (Namespace::SVG, "animate", "calcMode", "linear")
| (Namespace::SVG, "animate", "additive", "replace")
| (Namespace::SVG, "animate", "accumulate", "none")
| (Namespace::SVG, "animateColor", "begin", "0s")
| (Namespace::SVG, "animateColor", "dur", "indefinite")
| (Namespace::SVG, "animateColor", "min", "0")
| (Namespace::SVG, "animateColor", "opacity", "1")
| (Namespace::SVG, "animateColor", "restart", "always")
| (Namespace::SVG, "animateColor", "fill", "remove")
| (Namespace::SVG, "animateColor", "calcMode", "linear")
| (Namespace::SVG, "animateColor", "additive", "replace")
| (Namespace::SVG, "animateColor", "accumulate", "none")
| (Namespace::SVG, "animateMotion", "begin", "0s")
| (Namespace::SVG, "animateMotion", "dur", "indefinite")
| (Namespace::SVG, "animateMotion", "min", "0")
| (Namespace::SVG, "animateMotion", "rotate", "0")
| (Namespace::SVG, "animateMotion", "restart", "always")
| (Namespace::SVG, "animateMotion", "fill", "remove")
| (Namespace::SVG, "animateMotion", "calcMode", "linear")
| (Namespace::SVG, "animateMotion", "additive", "replace")
| (Namespace::SVG, "animateMotion", "accumulate", "none")
| (Namespace::SVG, "animateTransform", "begin", "0s")
| (Namespace::SVG, "animateTransform", "dur", "indefinite")
| (Namespace::SVG, "animateTransform", "min", "0")
| (Namespace::SVG, "animateTransform", "restart", "always")
| (Namespace::SVG, "animateTransform", "fill", "remove")
| (Namespace::SVG, "animateTransform", "calcMode", "linear")
| (Namespace::SVG, "animateTransform", "additive", "replace")
| (Namespace::SVG, "animateTransform", "accumulate", "none")
| (Namespace::SVG, "circle", "cx", "0")
| (Namespace::SVG, "circle", "cy", "0")
| (Namespace::SVG, "circle", "r", "0")
| (Namespace::SVG, "circle", "fill", "black")
| (Namespace::SVG, "circle", "fill-opacity", "1")
| (Namespace::SVG, "circle", "opacity", "1")
| (Namespace::SVG, "clipPath", "opacity", "1")
| (Namespace::SVG, "defs", "opacity", "1")
| (Namespace::SVG, "discard", "begin", "0s")
| (Namespace::SVG, "ellipse", "fill", "black")
| (Namespace::SVG, "ellipse", "fill-opacity", "1")
| (Namespace::SVG, "ellipse", "rx", "auto")
| (Namespace::SVG, "ellipse", "ry", "auto")
| (Namespace::SVG, "ellipse", "cx", "0")
| (Namespace::SVG, "ellipse", "cy", "0")
| (Namespace::SVG, "ellipse", "opacity", "1")
| (Namespace::SVG, "feBlend", "opacity", "1")
| (Namespace::SVG, "feColorMatrix", "opacity", "1")
| (Namespace::SVG, "feComponentTransfer", "opacity", "1")
| (Namespace::SVG, "feComposite", "opacity", "1")
| (Namespace::SVG, "feComposite", "k1", "0")
| (Namespace::SVG, "feComposite", "k2", "0")
| (Namespace::SVG, "feComposite", "k3", "0")
| (Namespace::SVG, "feComposite", "k4", "0")
| (Namespace::SVG, "feConvolveMatrix", "opacity", "1")
| (Namespace::SVG, "feDiffuseLighting", "opacity", "1")
| (Namespace::SVG, "feDisplacementMap", "opacity", "1")
| (Namespace::SVG, "feDisplacementMap", "yChannelSelector", "a")
| (Namespace::SVG, "feFlood", "opacity", "1")
| (Namespace::SVG, "feGaussianBlur", "opacity", "1")
| (Namespace::SVG, "feImage", "opacity", "1")
| (Namespace::SVG, "feMerge", "opacity", "1")
| (Namespace::SVG, "feMorphology", "opacity", "1")
| (Namespace::SVG, "feMorphology", "radius", "0")
| (Namespace::SVG, "feOffset", "opacity", "1")
| (Namespace::SVG, "fePointLight", "z", "1")
| (Namespace::SVG, "feSpecularLighting", "opacity", "1")
| (Namespace::SVG, "feSpotLight", "z", "1")
| (Namespace::SVG, "feTile", "opacity", "1")
| (Namespace::SVG, "feTurbulence", "opacity", "1")
| (Namespace::SVG, "filter", "opacity", "1")
| (Namespace::SVG, "font", "opacity", "1")
| (Namespace::SVG, "foreignObject", "opacity", "1")
| (Namespace::SVG, "g", "opacity", "1")
| (Namespace::SVG, "glyph", "opacity", "1")
| (Namespace::SVG, "glyphRef", "opacity", "1")
| (Namespace::SVG, "image", "opacity", "1")
| (Namespace::SVG, "line", "opacity", "1")
| (Namespace::SVG, "line", "y1", "0")
| (Namespace::SVG, "line", "y2", "0")
| (Namespace::SVG, "linearGradient", "opacity", "1")
| (Namespace::SVG, "linearGradient", "y1", "0")
| (Namespace::SVG, "linearGradient", "y2", "0")
| (
Namespace::SVG,
"linearGradient",
"gradientUnits",
"objectBoundingBox"
)
| (Namespace::SVG, "linearGradient", "spreadMethod", "pad")
| (Namespace::SVG, "marker", "opacity", "1")
| (Namespace::SVG, "marker", "refX", "0")
| (Namespace::SVG, "marker", "refY", "0")
| (Namespace::SVG, "mask", "opacity", "1")
| (Namespace::SVG, "missing-glyph", "opacity", "1")
| (Namespace::SVG, "path", "opacity", "1")
| (Namespace::SVG, "path", "fill", "black")
| (Namespace::SVG, "path", "fill-opacity", "1")
| (Namespace::SVG, "path", "fill-rule", "nonzero")
| (Namespace::SVG, "pattern", "opacity", "1")
| (Namespace::SVG, "polygon", "opacity", "1")
| (Namespace::SVG, "polygon", "fill", "black")
| (Namespace::SVG, "polygon", "fill-opacity", "1")
| (Namespace::SVG, "polygon", "fill-rule", "nonzero")
| (Namespace::SVG, "polyline", "opacity", "1")
| (Namespace::SVG, "polyline", "fill", "black")
| (Namespace::SVG, "polyline", "fill-opacity", "1")
| (Namespace::SVG, "polyline", "fill-rule", "nonzero")
| (Namespace::SVG, "radialGradient", "opacity", "1")
| (Namespace::SVG, "radialGradient", "cx", "50%")
| (Namespace::SVG, "radialGradient", "cy", "50%")
| (Namespace::SVG, "radialGradient", "fr", "0")
| (
Namespace::SVG,
"radialGradient",
"gradientUnits",
"objectBoundingBox"
)
| (Namespace::SVG, "radialGradient", "r", "50%")
| (Namespace::SVG, "radialGradient", "spreadMethod", "pad")
| (Namespace::SVG, "rect", "opacity", "1")
| (Namespace::SVG, "rect", "rx", "auto")
| (Namespace::SVG, "rect", "ry", "auto")
| (Namespace::SVG, "set", "begin", "0s")
| (Namespace::SVG, "set", "dur", "indefinite")
| (Namespace::SVG, "set", "min", "0")
| (Namespace::SVG, "set", "restart", "always")
| (Namespace::SVG, "stop", "opacity", "1")
| (Namespace::SVG, "svg", "opacity", "1")
| (Namespace::SVG, "svg", "zoomAndPan", "magnify")
| (Namespace::SVG, "switch", "opacity", "1")
| (Namespace::SVG, "symbol", "opacity", "1")
| (Namespace::SVG, "text", "opacity", "1")
| (Namespace::SVG, "text", "fill", "black")
| (Namespace::SVG, "text", "fill-opacity", "1")
| (Namespace::SVG, "text", "fill-rule", "nonzero")
| (Namespace::SVG, "text", "font-size", "medium")
| (Namespace::SVG, "text", "font-size-adjust", "none")
| (Namespace::SVG, "text", "font-stretch", "normal")
| (Namespace::SVG, "text", "font-style", "normal")
| (Namespace::SVG, "text", "font-variant", "normal")
| (Namespace::SVG, "text", "font-weight", "normal")
| (Namespace::SVG, "textPath", "opacity", "1")
| (Namespace::SVG, "textPath", "fill", "black")
| (Namespace::SVG, "textPath", "fill-opacity", "1")
| (Namespace::SVG, "textPath", "fill-rule", "nonzero")
| (Namespace::SVG, "textPath", "font-size", "medium")
| (Namespace::SVG, "textPath", "font-size-adjust", "none")
| (Namespace::SVG, "textPath", "font-stretch", "normal")
| (Namespace::SVG, "textPath", "font-style", "normal")
| (Namespace::SVG, "textPath", "font-variant", "normal")
| (Namespace::SVG, "textPath", "font-weight", "normal")
| (Namespace::SVG, "tref", "opacity", "1")
| (Namespace::SVG, "tref", "fill", "black")
| (Namespace::SVG, "tref", "fill-opacity", "1")
| (Namespace::SVG, "tref", "fill-rule", "nonzero")
| (Namespace::SVG, "tref", "font-size", "medium")
| (Namespace::SVG, "tref", "font-size-adjust", "none")
| (Namespace::SVG, "tref", "font-weight", "normal")
| (Namespace::SVG, "tref", "font-stretch", "normal")
| (Namespace::SVG, "tref", "font-style", "normal")
| (Namespace::SVG, "tref", "font-variant", "normal")
| (Namespace::SVG, "tspan", "opacity", "1")
| (Namespace::SVG, "tspan", "fill", "black")
| (Namespace::SVG, "tspan", "fill-opacity", "1")
| (Namespace::SVG, "tspan", "fill-rule", "nonzero")
| (Namespace::SVG, "tspan", "font-size", "medium")
| (Namespace::SVG, "tspan", "font-size-adjust", "none")
| (Namespace::SVG, "tspan", "font-stretch", "normal")
| (Namespace::SVG, "tspan", "font-style", "normal")
| (Namespace::SVG, "tspan", "font-variant", "normal")
| (Namespace::SVG, "tspan", "font-weight", "normal")
| (Namespace::SVG, "use", "opacity", "1")
| (Namespace::SVG, "view", "zoomAndPan", "magnify")
| (
Namespace::MATHML,
"math",
Expand Down
120 changes: 120 additions & 0 deletions crates/swc_html_minifier/tests/fixture/element/svg/input.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,125 @@
fill="black" stroke="black" />
</svg>

<svg viewBox="0 0 200 30" xmlns="http://www.w3.org/2000/svg">
<text y="20" font-weight="normal">Normal text</text>
<text x="100" y="20" font-weight="bold">Bold text</text>
</svg>

<svg viewBox="0 0 250 30" xmlns="http://www.w3.org/2000/svg">
<text y="20" font-variant="normal">Normal text</text>
<text x="100" y="20" font-variant="small-caps">Small-caps text</text>
</svg>

<svg viewBox="0 0 250 30" xmlns="http://www.w3.org/2000/svg">
<text y="20" font-style="normal">Normal font style</text>
<text x="150" y="20" font-style="italic">Italic font style</text>
</svg>

<svg viewBox="0 0 200 30" xmlns="http://www.w3.org/2000/svg">
<text y="20" font-size="medium">smaller</text>
<textPath y="20" font-size="medium">smaller</textPath>
<text x="100" y="20" font-size="2em">2em</text>
</svg>

<svg viewBox="0 0 300 100" xmlns="http://www.w3.org/2000/svg">
<!-- Simple color fill -->
<circle cx="50" cy="50" r="40" fill="pink" />

<!-- Fill circle with a gradient -->
<defs>
<radialGradient id="myGradient">
<stop offset="0%" stop-color="pink" />
<stop offset="100%" stop-color="black" />
</radialGradient>
</defs>

<circle cx="150" cy="50" r="40" fill="url(#myGradient)" />

<!--
Keeping the final state of an animated circle
which is a circle with a radius of 40.
-->
<circle cx="250" cy="50" r="20">
<animate attributeType="XML"
attributeName="r"
from="0" to="40" dur="5s"
fill="freeze" />
</circle>
</svg>

<svg viewBox="0 0 400 100" xmlns="http://www.w3.org/2000/svg">
<!-- Default fill opacity: 1 -->
<circle cx="50" cy="50" r="40" fill-opacity="1" />

<circle cx="50" cy="50" r="40" />

<!-- Fill opacity as a number -->
<circle cx="150" cy="50" r="40"
fill-opacity="0.7" />

<!-- Fill opacity as a percentage -->
<circle cx="250" cy="50" r="40"
fill-opacity="50%" />

<!-- Fill opacity as a CSS property -->
<circle cx="350" cy="50" r="40"
style="fill-opacity: .25;" />
</svg>

<svg>
<feMorphology radius="0"></feMorphology>
</svg>

<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
<filter id="composite1" x="0" y="0" width="100%" height="100%">
<feComposite in2="SourceGraphic" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" />
</filter>
<filter id="composite2" x="0" y="0" width="100%" height="100%">
<feComposite in2="SourceGraphic" operator="arithmetic" k1="10" k2="0" k3="0" k4="0.3" />
</filter>

<image href="mdn.svg" x="0" y="0"
width="200" height="200" style="filter: url(#composite1);" />
<image href="mdn.svg" x="0" y="0"
width="200" height="200" style="filter: url(#composite2); transform: translateX(220px);" />
</svg>

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<line x1="1" x2="9" y1="0" y2="0" stroke="red" />
<line x1="1" x2="9" y1="5" y2="5" stroke="green" />
<line x1="1" x2="9" y1="5" y2="9" stroke="blue" />
</svg>

<svg viewBox="0 0 440 160" xmlns="http://www.w3.org/2000/svg">
<filter id="displacementFilter">
<feImage xlink:href="mdn.svg"
x="0" y="0" width="100%" height="100%" result="abc"/>
<feDisplacementMap in2="abc" in="SourceGraphic"
scale="30" yChannelSelector="A"/>
</filter>
<filter id="displacementFilter2">
<feImage xlink:href="mdn.svg"
x="0" y="0" width="100%" height="100%" result="abc"/>
<feDisplacementMap in2="abc" in="SourceGraphic"
scale="30" yChannelSelector="B"/>
</filter>

<text x="10" y="60" font-size="50"
filter="url(#displacementFilter)">Some displaced text</text>
<text x="10" y="120" font-size="50"
filter="url(#displacementFilter2)">Some displaced text</text>
</svg>

<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" zoomAndPan="magnify">
<filter id="diffuseLighting" x="0" y="0" width="100%" height="100%">
<feDiffuseLighting in="SourceGraphic" zoomAndPan="1">
<fePointLight x="60" y="60" z="20" />
</feDiffuseLighting>
</filter>

<rect x="0" y="0" width="200" height="200" style="filter: url(#diffuseLighting);" />
</svg>

</body>
</html>

1 comment on commit 8bc9a40

@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: 8bc9a40 Previous: 451f346 Ratio
es/full/minify/libraries/antd 1662146145 ns/iter (± 15216116) 1652853443 ns/iter (± 35852042) 1.01
es/full/minify/libraries/d3 419494010 ns/iter (± 6611879) 415369277 ns/iter (± 12468625) 1.01
es/full/minify/libraries/echarts 1644671217 ns/iter (± 53901084) 1667385520 ns/iter (± 171997926) 0.99
es/full/minify/libraries/jquery 94324877 ns/iter (± 3189626) 100324122 ns/iter (± 7542226) 0.94
es/full/minify/libraries/lodash 122723188 ns/iter (± 1333754) 141058079 ns/iter (± 10071839) 0.87
es/full/minify/libraries/moment 72425453 ns/iter (± 10751541) 60100871 ns/iter (± 2479905) 1.21
es/full/minify/libraries/react 18354875 ns/iter (± 373161) 19092057 ns/iter (± 1743158) 0.96
es/full/minify/libraries/terser 613969423 ns/iter (± 11299416) 631676402 ns/iter (± 8912932) 0.97
es/full/minify/libraries/three 549912361 ns/iter (± 3646780) 582049754 ns/iter (± 11887848) 0.94
es/full/minify/libraries/typescript 3520856081 ns/iter (± 118014702) 3638965444 ns/iter (± 66056848) 0.97
es/full/minify/libraries/victory 735183759 ns/iter (± 9997454) 744798561 ns/iter (± 11486945) 0.99
es/full/minify/libraries/vue 142448290 ns/iter (± 7326756) 150361652 ns/iter (± 2048959) 0.95
es/full/codegen/es3 31312 ns/iter (± 376) 32574 ns/iter (± 1816) 0.96
es/full/codegen/es5 31213 ns/iter (± 279) 32720 ns/iter (± 528) 0.95
es/full/codegen/es2015 31502 ns/iter (± 1297) 32768 ns/iter (± 309) 0.96
es/full/codegen/es2016 33474 ns/iter (± 5334) 32720 ns/iter (± 819) 1.02
es/full/codegen/es2017 33743 ns/iter (± 2177) 32751 ns/iter (± 963) 1.03
es/full/codegen/es2018 33826 ns/iter (± 1833) 32269 ns/iter (± 235) 1.05
es/full/codegen/es2019 33215 ns/iter (± 2423) 32166 ns/iter (± 410) 1.03
es/full/codegen/es2020 33929 ns/iter (± 2321) 32176 ns/iter (± 740) 1.05
es/full/all/es3 221571778 ns/iter (± 22293129) 186380470 ns/iter (± 10362352) 1.19
es/full/all/es5 177153341 ns/iter (± 20838681) 174063229 ns/iter (± 19475353) 1.02
es/full/all/es2015 154340594 ns/iter (± 11720972) 140416177 ns/iter (± 9988106) 1.10
es/full/all/es2016 167488898 ns/iter (± 7774203) 142268717 ns/iter (± 7470858) 1.18
es/full/all/es2017 151080458 ns/iter (± 25775726) 141985677 ns/iter (± 12245599) 1.06
es/full/all/es2018 136654803 ns/iter (± 4561596) 139278237 ns/iter (± 7287309) 0.98
es/full/all/es2019 139653159 ns/iter (± 10623667) 139044874 ns/iter (± 7906559) 1.00
es/full/all/es2020 130967999 ns/iter (± 6363516) 134786140 ns/iter (± 6336512) 0.97
es/full/parser 732321 ns/iter (± 34785) 723624 ns/iter (± 34380) 1.01
es/full/base/fixer 29657 ns/iter (± 983) 29533 ns/iter (± 1042) 1.00
es/full/base/resolver_and_hygiene 89078 ns/iter (± 5011) 87738 ns/iter (± 4342) 1.02
serialization of ast node 207 ns/iter (± 5) 207 ns/iter (± 2) 1
serialization of serde 222 ns/iter (± 5) 224 ns/iter (± 3) 0.99

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

Please sign in to comment.