perf(css/minifier): Merge passes and reduce clone (#5822)

This commit is contained in:
Donny/강동윤 2022-09-11 18:24:53 +09:00 committed by GitHub
parent 35736a313d
commit 9e81c2639b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 97 additions and 127 deletions

View File

@ -1,3 +1 @@
pub mod alpha_value;
pub mod at_rule;
pub mod transform_function;

View File

@ -1,20 +1,10 @@
use swc_atoms::js_word;
use swc_common::DUMMY_SP;
use swc_css_ast::*;
use swc_css_visit::{VisitMut, VisitMutWith};
pub fn compress_alpha_value() -> impl VisitMut {
CompressAlphaValue { preserve: true }
}
struct CompressAlphaValue {
preserve: bool,
}
impl VisitMut for CompressAlphaValue {
fn visit_mut_alpha_value(&mut self, alpha_value: &mut AlphaValue) {
alpha_value.visit_mut_children_with(self);
use super::Compressor;
impl Compressor {
pub(super) fn compress_alpha_value(&mut self, alpha_value: &mut AlphaValue) {
match alpha_value {
AlphaValue::Percentage(Percentage {
value: number,
@ -45,34 +35,11 @@ impl VisitMut for CompressAlphaValue {
}
}
fn visit_mut_declaration(&mut self, declaration: &mut Declaration) {
declaration.visit_mut_children_with(self);
if let DeclarationName::Ident(Ident { value, .. }) = &declaration.name {
match value.to_ascii_lowercase() {
js_word!("opacity")
| js_word!("fill-opacity")
| js_word!("stroke-opacity")
| js_word!("shape-image-threshold") => {
let old_preserve = self.preserve;
self.preserve = false;
declaration.visit_mut_children_with(self);
self.preserve = old_preserve;
}
_ => {
declaration.visit_mut_children_with(self);
}
}
}
}
fn visit_mut_component_value(&mut self, component_value: &mut ComponentValue) {
component_value.visit_mut_children_with(self);
if self.preserve {
pub(super) fn compress_alpha_value_in_component_value(
&mut self,
component_value: &mut ComponentValue,
) {
if self.ctx.preserve_alpha_value {
return;
}

View File

@ -141,7 +141,7 @@ macro_rules! make_color {
Color::AbsoluteColorBase(AbsoluteColorBase::HexColor(HexColor {
span: $span,
value: value.clone().into(),
value: value.into(),
raw: None,
}))
} else {
@ -207,7 +207,7 @@ macro_rules! make_color {
Color::AbsoluteColorBase(AbsoluteColorBase::HexColor(HexColor {
span: $span,
value: value.clone().into(),
value: value.into(),
raw: None,
}))
}

View File

@ -2,7 +2,7 @@ use std::ops::{Deref, DerefMut};
use super::Compressor;
#[derive(Default, Clone, Copy)]
#[derive(Clone, Copy)]
pub(super) struct Ctx {
pub in_math_function: bool,
@ -11,6 +11,19 @@ pub(super) struct Ctx {
pub in_transform_function: bool,
pub in_keyframe_block: bool,
pub preserve_alpha_value: bool,
}
impl Default for Ctx {
fn default() -> Self {
Self {
preserve_alpha_value: true,
in_math_function: false,
in_logic_combinator_selector: false,
in_transform_function: false,
in_keyframe_block: false,
}
}
}
impl Compressor {

View File

@ -4,6 +4,7 @@ use swc_css_visit::{VisitMut, VisitMutWith};
use self::ctx::Ctx;
mod alpha_value;
mod angle;
mod color;
mod ctx;
@ -15,6 +16,7 @@ mod keyframes;
mod length;
mod selector;
mod time;
mod transform_function;
mod unicode_range;
mod url;
@ -30,6 +32,8 @@ struct Compressor {
impl VisitMut for Compressor {
fn visit_mut_alpha_value(&mut self, n: &mut AlphaValue) {
n.visit_mut_children_with(self);
self.compress_alpha_value(n);
}
fn visit_mut_stylesheet(&mut self, n: &mut Stylesheet) {
@ -63,7 +67,24 @@ impl VisitMut for Compressor {
}
fn visit_mut_declaration(&mut self, n: &mut Declaration) {
n.visit_mut_children_with(self);
if let DeclarationName::Ident(Ident { value, .. }) = &n.name {
match value.to_ascii_lowercase() {
js_word!("opacity")
| js_word!("fill-opacity")
| js_word!("stroke-opacity")
| js_word!("shape-image-threshold") => {
n.visit_mut_children_with(&mut *self.with_ctx(Ctx {
preserve_alpha_value: false,
..self.ctx
}));
}
_ => {
n.visit_mut_children_with(self);
}
}
} else {
n.visit_mut_children_with(self);
}
self.compress_declaration(n);
}
@ -102,10 +123,14 @@ impl VisitMut for Compressor {
fn visit_mut_component_value(&mut self, n: &mut ComponentValue) {
n.visit_mut_children_with(self);
self.compress_alpha_value_in_component_value(n);
self.compress_component_value_for_length(n);
self.compress_easing_function(n);
self.compress_transform_function(n);
self.compress_angle_in_component_value(n);
}

View File

@ -1,3 +1,5 @@
use std::mem::take;
use swc_atoms::js_word;
use swc_common::{EqIgnoreSpan, DUMMY_SP};
use swc_css_ast::*;
@ -6,78 +8,28 @@ use super::Compressor;
impl Compressor {
pub(super) fn comrpess_selector_list(&mut self, selector_list: &mut SelectorList) {
let mut already_seen: Vec<ComplexSelector> = vec![];
selector_list.children.retain(|children| {
for already_seen_complex_selector in &already_seen {
if already_seen_complex_selector.eq_ignore_span(children) {
return false;
}
}
already_seen.push(children.clone());
true
});
dedup(&mut selector_list.children);
}
pub(super) fn compress_forgiving_selector_list(
&mut self,
forgiving_selector_list: &mut ForgivingSelectorList,
) {
let mut already_seen: Vec<ForgivingComplexSelector> = vec![];
forgiving_selector_list.children.retain(|children| {
for already_seen_complex_selector in &already_seen {
if already_seen_complex_selector.eq_ignore_span(children) {
return false;
}
}
already_seen.push(children.clone());
true
});
dedup(&mut forgiving_selector_list.children);
}
pub(super) fn compress_relative_selector_list(
&mut self,
relative_selector_list: &mut RelativeSelectorList,
) {
let mut already_seen: Vec<RelativeSelector> = vec![];
relative_selector_list.children.retain(|children| {
for already_seen_complex_selector in &already_seen {
if already_seen_complex_selector.eq_ignore_span(children) {
return false;
}
}
already_seen.push(children.clone());
true
});
dedup(&mut relative_selector_list.children);
}
pub(super) fn compress_forgiving_relative_selector_list(
&mut self,
forgiving_relative_selector_list: &mut ForgivingRelativeSelectorList,
) {
let mut already_seen: Vec<ForgivingRelativeSelector> = vec![];
forgiving_relative_selector_list
.children
.retain(|children| {
for already_seen_complex_selector in &already_seen {
if already_seen_complex_selector.eq_ignore_span(children) {
return false;
}
}
already_seen.push(children.clone());
true
});
dedup(&mut forgiving_relative_selector_list.children);
}
pub(super) fn compress_an_plus_b(&mut self, an_plus_b: &mut AnPlusB) {
@ -353,3 +305,36 @@ impl Compressor {
}
}
}
fn dedup<T>(v: &mut Vec<T>)
where
T: EqIgnoreSpan,
{
let mut remove_list = vec![];
for (i, i1) in v.iter().enumerate() {
for (j, j1) in v.iter().enumerate() {
if i < j && i1.eq_ignore_span(j1) {
remove_list.push(j);
}
}
}
// Fast path. We don't face real duplciate in most cases.
if remove_list.is_empty() {
return;
}
let new = take(v)
.into_iter()
.enumerate()
.filter_map(|(idx, value)| {
if remove_list.contains(&idx) {
None
} else {
Some(value)
}
})
.collect::<Vec<_>>();
*v = new;
}

View File

@ -1,19 +1,10 @@
use swc_atoms::js_word;
use swc_css_ast::*;
use swc_css_visit::{VisitMut, VisitMutWith};
pub fn compress_transform_function() -> impl VisitMut {
CompressTransformFunction {}
}
struct CompressTransformFunction {}
impl CompressTransformFunction {}
impl VisitMut for CompressTransformFunction {
fn visit_mut_component_value(&mut self, component_value: &mut ComponentValue) {
component_value.visit_mut_children_with(self);
use super::Compressor;
impl Compressor {
pub(super) fn compress_transform_function(&self, component_value: &mut ComponentValue) {
match component_value {
ComponentValue::Function(Function {
name,

View File

@ -45,7 +45,7 @@ impl Compressor {
url.value = Some(UrlValue::Raw(UrlValueRaw {
span: *span,
value: escaped.clone().into(),
value: escaped.into(),
before: None,
raw: None,
after: None,

View File

@ -5,14 +5,7 @@
use swc_css_ast::*;
use swc_css_visit::VisitMutWith;
use self::{
compress::{
alpha_value::compress_alpha_value, at_rule::compress_at_rule,
transform_function::compress_transform_function,
},
compressor::compressor,
options::MinifyOptions,
};
use self::{compress::at_rule::compress_at_rule, compressor::compressor, options::MinifyOptions};
mod compress;
mod compressor;
@ -20,7 +13,5 @@ pub mod options;
pub fn minify(stylesheet: &mut Stylesheet, _options: MinifyOptions) {
stylesheet.visit_mut_with(&mut compressor());
stylesheet.visit_mut_with(&mut compress_alpha_value());
stylesheet.visit_mut_with(&mut compress_transform_function());
stylesheet.visit_mut_with(&mut compress_at_rule());
}

View File

@ -1 +1 @@
.class1{opacity:0}.class2{opacity:0}.class3{opacity:.5}.class4{opacity:.5}.class5{opacity:1}.class6{opacity:1}.class7{shape-image-threshold:.7}.class8{fill-opacity:.5}.class9{stroke-opacity:.5}.class10{shape-image-threshold:.5}.class11{opacity:53%}.class12{OPACITY:0}.class13{color:#7b7b7b}.class14{color:rgba(123,123,123,.2)}.class15{color:rgba(123,123,123,1%)}.class16{color:rgba(123,123,123,0)}.class17{color:#7b7b7b}.class18{color:rgba(123,123,123,.2)}.class19{color:rgba(123,123,123,.5)}.class20{color:rgba(123,123,123,.53)}.class21{color:rgba(123,123,123,.1)}.class22{color:rgba(123,123,123,.1)}.class23{color:rgba(123,123,123,1%)}.class24{color:rgba(123,123,123,9%)}.class25{color:rgba(123,123,123,0)}.class26{color:rgba(123,123,123,0)}
.class1{opacity:0}.class2{opacity:0}.class3{opacity:.5}.class4{opacity:.5}.class5{opacity:1}.class6{opacity:1}.class7{shape-image-threshold:.7}.class8{fill-opacity:.5}.class9{stroke-opacity:.5}.class10{shape-image-threshold:.5}.class11{opacity:53%}.class12{OPACITY:0}.class13{color:#7b7b7b}.class14{color:rgba(123,123,123,.2)}.class15{color:rgba(123,123,123,.01)}.class16{color:rgba(123,123,123,0)}.class17{color:#7b7b7b}.class18{color:rgba(123,123,123,.2)}.class19{color:rgba(123,123,123,.5)}.class20{color:rgba(123,123,123,.53)}.class21{color:rgba(123,123,123,.1)}.class22{color:rgba(123,123,123,.1)}.class23{color:rgba(123,123,123,.01)}.class24{color:rgba(123,123,123,.09)}.class25{color:rgba(123,123,123,0)}.class26{color:rgba(123,123,123,0)}

View File

@ -1 +1 @@
.color{color:rgb(from rgba(0,0,0,0)255 255 255)}.color-1{color:rgb(from red 255 255 255)}.color-2{color:rgb(from red 255 255 255)}.color-3{color:rgb(from#f00 255 255 255)}.color-4{color:rgb(from#eee8aa 255 255 255)}.color-5{color:rgb(from#ff0 255 255 255)}.color-6{color:rgb(from snow 255 255 255)}.color-7{color:rgba(123,123,123,0)}.color-8{color:#7b7b7b}.color-9{color:#7b7b7b}.color-10{color:#7b7b7b}.color-11{color:#7b7b7b}.color-12{color:rgba(51,102,77,.23)}.color-13{color:#7b7b7b}.color-14{color:#6496c8}.class-15{color:#7b7b7b}.class-16{color:rgba(123,123,123,.99)}.class-17{color:#7b7b7b}.class-18{color:rgba(179,82,31,.13)}.class-19{color:rgba(180,82,31,.13)}.class-20{color:rgba(181,82,31,.13)}.class-21{color:rgba(182,82,31,.13)}.class-22{color:rgba(184,82,31,.13)}.class-23{color:rgba(181,181,181,.13)}.class-24{color:rgba(182,181,181,.13)}.class-25{color:rgba(181,181,181,.1%)}.class-26{color:rgba(181,181,181,.4%)}.color-27{color:rgb(from#eee8aa 255 255 255)}.color-28{color:rgb(from teal 255 255 255)}.color-29{color:rgb(from red 255 255 255)}.color-30{color:rgb(from red 255 255 255)}.class-31{color:#ff0800;color:gray;color:#000;color:#80ff00;color:#a6ff00;color:#f9ff00;color:#80ff00;color:red;color:red;color:red;color:#00ffae;color:red;color:#ff00bf;color:#8000ff;color:#0040ff;color:#0ff;color:#00ff40;color:#80ff00;color:#ffbf00;color:red;color:red;color:#ff00bf;color:rgba(128,0,255,.5);color:rgba(0,64,255,.5);color:rgba(0,255,255,.5);color:rgba(0,255,64,.5);color:rgba(128,255,0,.5);color:rgba(255,191,0,.5);color:rgba(255,0,0,.5);color:red;color:#ff00bf;color:#8000ff;color:#0040ff;color:#0ff;color:#00ff40;color:#80ff00;color:#ffbf00;color:red;color:red;color:#ff00bf;color:rgba(128,0,255,.5);color:rgba(0,64,255,.5);color:rgba(0,255,255,.5);color:rgba(0,255,64,.5);color:rgba(128,255,0,.5);color:rgba(255,191,0,.5);color:rgba(255,0,0,.5);color:#ff0400;color:#ff0800;color:#ff0d00}.class-32{color:gray;color:#4d7f4d;color:#fff;color:#fd3;color:#ccb333;color:green;color:#000;color:gray;color:#33b333;color:gray;color:gray;color:hwb(90deg 50%50%,.2);color:gray;color:hwb(90 50%50%.2);color:#6b8056;color:#4d7f4d;color:rgba(77,127,77,.5);color:red;color:red;color:rgba(255,0,0,0);color:rgba(255,0,0,0);color:#0f0;color:#0f0;color:#cfc;color:#cfc;color:green;color:green;color:rgba(77,127,77,0);color:rgba(77,127,77,0);color:rgba(170,170,170,0);color:rgba(170,170,170,0);color:#4d7f4d}.class-33{color:red}.class-34{color:rgba(2,3,4,.5)}.class-35{color:rgba(2,3,4,.5)}.class-36{color:#0f0}.class-37{color:rgba(0,255,0,.25)}.class-38{color:#000304}.class-39{color:#64c8ff}.class-40{color:rgba(20,10,0,0)}.class-41{color:#fff}.class-41{color:#000}.class-42{color:rgba(0,0,0,0)}.class-43{color:maroon}.class-44{color:rgba(128,0,0,0)}.class-45{color:rgba(0,0,0,.5)}.class-46{color:#300}.class-47{color:rgba(51,0,0,0)}.class-48{color:rgba(0,0,0,.5)}.class-49{color:#000}.class-50{color:rgba(0,0,0,0)}.class-51{color:maroon}.class-52{color:rgba(128,0,0,0)}.class-53{color:rgba(0,0,0,.5)}.class-54{color:#300}.class-55{color:rgba(51,0,0,0)}.class-56{color:rgba(0,0,0,.5)}.class-57{color:#59a659}.class-58{color:rgba(77,127,77,.5)}.class-59{color:red}.class-60{color:red}.class-61{color:rgba(255,0,0,0)}.class-62{color:rgba(255,0,0,0)}.class-63{color:#0f0}.class-64{color:#0f0}.class-65{color:#cfc}.class-66{color:#cfc}.class-67{color:green}.class-68{color:green}.class-69{color:rgba(77,127,77,0)}.class-70{color:rgba(77,127,77,0)}.class-71{color:rgba(170,170,170,0)}.class-72{color:rgba(170,170,170,0)}.class-73{color:#fff}.class-74{color:#000}.class-75{color:#fff}.class-76{color:#000}.class-77{color:#000}.class-78{color:#000}.class-79{color:#fff}.class-80{color:#646464}.class-81{color:#646464}.class-82{color:rgba(100,100,100,0)}.class-83{color:rgba(100,100,100,0)}
.color{color:rgb(from rgba(0,0,0,0)255 255 255)}.color-1{color:rgb(from red 255 255 255)}.color-2{color:rgb(from red 255 255 255)}.color-3{color:rgb(from#f00 255 255 255)}.color-4{color:rgb(from#eee8aa 255 255 255)}.color-5{color:rgb(from#ff0 255 255 255)}.color-6{color:rgb(from snow 255 255 255)}.color-7{color:rgba(123,123,123,0)}.color-8{color:#7b7b7b}.color-9{color:#7b7b7b}.color-10{color:#7b7b7b}.color-11{color:#7b7b7b}.color-12{color:rgba(51,102,77,.23)}.color-13{color:#7b7b7b}.color-14{color:#6496c8}.class-15{color:#7b7b7b}.class-16{color:rgba(123,123,123,.99)}.class-17{color:#7b7b7b}.class-18{color:rgba(179,82,31,.13)}.class-19{color:rgba(180,82,31,.13)}.class-20{color:rgba(181,82,31,.13)}.class-21{color:rgba(182,82,31,.13)}.class-22{color:rgba(184,82,31,.13)}.class-23{color:rgba(181,181,181,.13)}.class-24{color:rgba(182,181,181,.13)}.class-25{color:rgba(181,181,181,.001)}.class-26{color:rgba(181,181,181,.004)}.color-27{color:rgb(from#eee8aa 255 255 255)}.color-28{color:rgb(from teal 255 255 255)}.color-29{color:rgb(from red 255 255 255)}.color-30{color:rgb(from red 255 255 255)}.class-31{color:#ff0800;color:gray;color:#000;color:#80ff00;color:#a6ff00;color:#f9ff00;color:#80ff00;color:red;color:red;color:red;color:#00ffae;color:red;color:#ff00bf;color:#8000ff;color:#0040ff;color:#0ff;color:#00ff40;color:#80ff00;color:#ffbf00;color:red;color:red;color:#ff00bf;color:rgba(128,0,255,.5);color:rgba(0,64,255,.5);color:rgba(0,255,255,.5);color:rgba(0,255,64,.5);color:rgba(128,255,0,.5);color:rgba(255,191,0,.5);color:rgba(255,0,0,.5);color:red;color:#ff00bf;color:#8000ff;color:#0040ff;color:#0ff;color:#00ff40;color:#80ff00;color:#ffbf00;color:red;color:red;color:#ff00bf;color:rgba(128,0,255,.5);color:rgba(0,64,255,.5);color:rgba(0,255,255,.5);color:rgba(0,255,64,.5);color:rgba(128,255,0,.5);color:rgba(255,191,0,.5);color:rgba(255,0,0,.5);color:#ff0400;color:#ff0800;color:#ff0d00}.class-32{color:gray;color:#4d7f4d;color:#fff;color:#fd3;color:#ccb333;color:green;color:#000;color:gray;color:#33b333;color:gray;color:gray;color:hwb(90deg 50%50%,.2);color:gray;color:hwb(90 50%50%.2);color:#6b8056;color:#4d7f4d;color:rgba(77,127,77,.5);color:red;color:red;color:rgba(255,0,0,0);color:rgba(255,0,0,0);color:#0f0;color:#0f0;color:#cfc;color:#cfc;color:green;color:green;color:rgba(77,127,77,0);color:rgba(77,127,77,0);color:rgba(170,170,170,0);color:rgba(170,170,170,0);color:#4d7f4d}.class-33{color:red}.class-34{color:rgba(2,3,4,.5)}.class-35{color:rgba(2,3,4,.5)}.class-36{color:#0f0}.class-37{color:rgba(0,255,0,.25)}.class-38{color:#000304}.class-39{color:#64c8ff}.class-40{color:rgba(20,10,0,0)}.class-41{color:#fff}.class-41{color:#000}.class-42{color:rgba(0,0,0,0)}.class-43{color:maroon}.class-44{color:rgba(128,0,0,0)}.class-45{color:rgba(0,0,0,.5)}.class-46{color:#300}.class-47{color:rgba(51,0,0,0)}.class-48{color:rgba(0,0,0,.5)}.class-49{color:#000}.class-50{color:rgba(0,0,0,0)}.class-51{color:maroon}.class-52{color:rgba(128,0,0,0)}.class-53{color:rgba(0,0,0,.5)}.class-54{color:#300}.class-55{color:rgba(51,0,0,0)}.class-56{color:rgba(0,0,0,.5)}.class-57{color:#59a659}.class-58{color:rgba(77,127,77,.5)}.class-59{color:red}.class-60{color:red}.class-61{color:rgba(255,0,0,0)}.class-62{color:rgba(255,0,0,0)}.class-63{color:#0f0}.class-64{color:#0f0}.class-65{color:#cfc}.class-66{color:#cfc}.class-67{color:green}.class-68{color:green}.class-69{color:rgba(77,127,77,0)}.class-70{color:rgba(77,127,77,0)}.class-71{color:rgba(170,170,170,0)}.class-72{color:rgba(170,170,170,0)}.class-73{color:#fff}.class-74{color:#000}.class-75{color:#fff}.class-76{color:#000}.class-77{color:#000}.class-78{color:#000}.class-79{color:#fff}.class-80{color:#646464}.class-81{color:#646464}.class-82{color:rgba(100,100,100,0)}.class-83{color:rgba(100,100,100,0)}

File diff suppressed because one or more lines are too long