mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 10:12:42 +03:00
perf(css/minifier): Remove redundant clone (#6579)
This commit is contained in:
parent
a475f61ac3
commit
70ac0286e5
@ -1,5 +1,5 @@
|
|||||||
use is_macro::Is;
|
use is_macro::Is;
|
||||||
use swc_common::{ast_node, EqIgnoreSpan, Span};
|
use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AlphaValue, AtRule, CalcSum, CmykComponent, Color, ComplexSelector, DashedIdent, Delimiter,
|
AlphaValue, AtRule, CalcSum, CmykComponent, Color, ComplexSelector, DashedIdent, Delimiter,
|
||||||
@ -46,6 +46,12 @@ pub enum QualifiedRulePrelude {
|
|||||||
ListOfComponentValues(ListOfComponentValues),
|
ListOfComponentValues(ListOfComponentValues),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Take for QualifiedRulePrelude {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Self::SelectorList(Take::dummy())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[ast_node]
|
#[ast_node]
|
||||||
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
||||||
pub enum StyleBlock {
|
pub enum StyleBlock {
|
||||||
@ -67,6 +73,16 @@ pub struct SimpleBlock {
|
|||||||
pub value: Vec<ComponentValue>,
|
pub value: Vec<ComponentValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Take for SimpleBlock {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Self {
|
||||||
|
span: Take::dummy(),
|
||||||
|
name: Take::dummy(),
|
||||||
|
value: Take::dummy(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[ast_node("Function")]
|
#[ast_node("Function")]
|
||||||
#[derive(Eq, Hash, EqIgnoreSpan)]
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
|
@ -12,6 +12,15 @@ pub struct SelectorList {
|
|||||||
pub children: Vec<ComplexSelector>,
|
pub children: Vec<ComplexSelector>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Take for SelectorList {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Self {
|
||||||
|
span: Take::dummy(),
|
||||||
|
children: Take::dummy(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[ast_node("SelectorList")]
|
#[ast_node("SelectorList")]
|
||||||
#[derive(Eq, Hash, EqIgnoreSpan)]
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
||||||
pub struct ForgivingSelectorList {
|
pub struct ForgivingSelectorList {
|
||||||
|
@ -6,7 +6,7 @@ use std::{
|
|||||||
use is_macro::Is;
|
use is_macro::Is;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use swc_atoms::{Atom, JsWord};
|
use swc_atoms::{Atom, JsWord};
|
||||||
use swc_common::{ast_node, EqIgnoreSpan, Span};
|
use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
|
||||||
|
|
||||||
#[ast_node("PreservedToken")]
|
#[ast_node("PreservedToken")]
|
||||||
#[derive(Eq, Hash, EqIgnoreSpan)]
|
#[derive(Eq, Hash, EqIgnoreSpan)]
|
||||||
@ -15,6 +15,15 @@ pub struct TokenAndSpan {
|
|||||||
pub token: Token,
|
pub token: Token,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Take for TokenAndSpan {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Self {
|
||||||
|
span: Take::dummy(),
|
||||||
|
token: Take::dummy(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Is, EqIgnoreSpan)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Is, EqIgnoreSpan)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "rkyv",
|
feature = "rkyv",
|
||||||
@ -147,6 +156,12 @@ pub enum Token {
|
|||||||
RBrace,
|
RBrace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Take for Token {
|
||||||
|
fn dummy() -> Self {
|
||||||
|
Self::Semi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::derive_hash_xor_eq)]
|
#[allow(clippy::derive_hash_xor_eq)]
|
||||||
#[allow(clippy::transmute_float_to_int)]
|
#[allow(clippy::transmute_float_to_int)]
|
||||||
impl Hash for Token {
|
impl Hash for Token {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use std::mem::take;
|
use std::mem::take;
|
||||||
|
|
||||||
use swc_atoms::{js_word, JsWord};
|
use swc_atoms::{js_word, JsWord};
|
||||||
use swc_common::{collections::AHashMap, EqIgnoreSpan, Span, Spanned, SyntaxContext};
|
use swc_common::{
|
||||||
|
collections::AHashMap, util::take::Take, EqIgnoreSpan, Span, Spanned, SyntaxContext,
|
||||||
|
};
|
||||||
use swc_css_ast::*;
|
use swc_css_ast::*;
|
||||||
use swc_css_visit::{Visit, VisitMutWith, VisitWith};
|
use swc_css_visit::{Visit, VisitMutWith, VisitWith};
|
||||||
|
|
||||||
@ -144,10 +146,14 @@ impl Compressor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_selector_list(&self, left: &SelectorList, right: &SelectorList) -> SelectorList {
|
fn merge_selector_list(
|
||||||
let mut children = left.children.clone();
|
&self,
|
||||||
|
left: &mut SelectorList,
|
||||||
|
right: &mut SelectorList,
|
||||||
|
) -> SelectorList {
|
||||||
|
let mut children = left.children.take();
|
||||||
|
|
||||||
children.extend(right.children.clone());
|
children.extend(right.children.take());
|
||||||
|
|
||||||
SelectorList {
|
SelectorList {
|
||||||
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
||||||
@ -157,12 +163,12 @@ impl Compressor {
|
|||||||
|
|
||||||
fn merge_relative_selector_list(
|
fn merge_relative_selector_list(
|
||||||
&self,
|
&self,
|
||||||
left: &RelativeSelectorList,
|
left: &mut RelativeSelectorList,
|
||||||
right: &RelativeSelectorList,
|
right: &mut RelativeSelectorList,
|
||||||
) -> RelativeSelectorList {
|
) -> RelativeSelectorList {
|
||||||
let mut children = left.children.clone();
|
let mut children = left.children.take();
|
||||||
|
|
||||||
children.extend(right.children.clone());
|
children.extend(right.children.take());
|
||||||
|
|
||||||
RelativeSelectorList {
|
RelativeSelectorList {
|
||||||
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
||||||
@ -170,10 +176,10 @@ impl Compressor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_simple_block(&self, left: &SimpleBlock, right: &SimpleBlock) -> SimpleBlock {
|
fn merge_simple_block(&self, left: &mut SimpleBlock, right: &mut SimpleBlock) -> SimpleBlock {
|
||||||
let mut value = left.value.clone();
|
let mut value = left.value.take();
|
||||||
|
|
||||||
value.extend(right.value.clone());
|
value.extend(right.value.take());
|
||||||
|
|
||||||
SimpleBlock {
|
SimpleBlock {
|
||||||
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
||||||
@ -212,8 +218,8 @@ impl Compressor {
|
|||||||
|
|
||||||
fn try_merge_qualified_rules(
|
fn try_merge_qualified_rules(
|
||||||
&mut self,
|
&mut self,
|
||||||
left: &QualifiedRule,
|
left: &mut QualifiedRule,
|
||||||
right: &QualifiedRule,
|
right: &mut QualifiedRule,
|
||||||
) -> Option<QualifiedRule> {
|
) -> Option<QualifiedRule> {
|
||||||
if !self.can_merge_qualified_rules(left, right) {
|
if !self.can_merge_qualified_rules(left, right) {
|
||||||
return None;
|
return None;
|
||||||
@ -222,7 +228,7 @@ impl Compressor {
|
|||||||
// Merge when declarations are exactly equal
|
// Merge when declarations are exactly equal
|
||||||
// e.g. h1 { color: red } h2 { color: red }
|
// e.g. h1 { color: red } h2 { color: red }
|
||||||
if left.block.eq_ignore_span(&right.block) {
|
if left.block.eq_ignore_span(&right.block) {
|
||||||
match (&left.prelude, &right.prelude) {
|
match (&mut left.prelude, &mut right.prelude) {
|
||||||
(
|
(
|
||||||
QualifiedRulePrelude::SelectorList(prev_selector_list),
|
QualifiedRulePrelude::SelectorList(prev_selector_list),
|
||||||
QualifiedRulePrelude::SelectorList(current_selector_list),
|
QualifiedRulePrelude::SelectorList(current_selector_list),
|
||||||
@ -232,7 +238,7 @@ impl Compressor {
|
|||||||
let mut qualified_rule = QualifiedRule {
|
let mut qualified_rule = QualifiedRule {
|
||||||
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
||||||
prelude: QualifiedRulePrelude::SelectorList(selector_list),
|
prelude: QualifiedRulePrelude::SelectorList(selector_list),
|
||||||
block: left.block.clone(),
|
block: left.block.take(),
|
||||||
};
|
};
|
||||||
|
|
||||||
qualified_rule.visit_mut_children_with(self);
|
qualified_rule.visit_mut_children_with(self);
|
||||||
@ -250,7 +256,7 @@ impl Compressor {
|
|||||||
let mut qualified_rule = QualifiedRule {
|
let mut qualified_rule = QualifiedRule {
|
||||||
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
||||||
prelude: QualifiedRulePrelude::RelativeSelectorList(relative_selector_list),
|
prelude: QualifiedRulePrelude::RelativeSelectorList(relative_selector_list),
|
||||||
block: left.block.clone(),
|
block: left.block.take(),
|
||||||
};
|
};
|
||||||
|
|
||||||
qualified_rule.visit_mut_children_with(self);
|
qualified_rule.visit_mut_children_with(self);
|
||||||
@ -264,10 +270,10 @@ impl Compressor {
|
|||||||
// Merge when both selectors are exactly equal
|
// Merge when both selectors are exactly equal
|
||||||
// e.g. a { color: blue } a { font-weight: bold }
|
// e.g. a { color: blue } a { font-weight: bold }
|
||||||
if left.prelude.eq_ignore_span(&right.prelude) {
|
if left.prelude.eq_ignore_span(&right.prelude) {
|
||||||
let block = self.merge_simple_block(&left.block, &right.block);
|
let block = self.merge_simple_block(&mut left.block, &mut right.block);
|
||||||
let mut qualified_rule = QualifiedRule {
|
let mut qualified_rule = QualifiedRule {
|
||||||
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
|
||||||
prelude: left.prelude.clone(),
|
prelude: left.prelude.take(),
|
||||||
block,
|
block,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -299,14 +305,14 @@ impl Compressor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_merge_at_rule(&mut self, left: &AtRule, right: &AtRule) -> Option<AtRule> {
|
fn try_merge_at_rule(&mut self, left: &mut AtRule, right: &mut AtRule) -> Option<AtRule> {
|
||||||
// Merge when both at-rule's prelude is exactly equal
|
// Merge when both at-rule's prelude is exactly equal
|
||||||
// e.g.
|
// e.g.
|
||||||
// @media print { .color { color: red; } }
|
// @media print { .color { color: red; } }
|
||||||
// @media print { .color { color: blue; } }
|
// @media print { .color { color: blue; } }
|
||||||
if left.prelude.eq_ignore_span(&right.prelude) {
|
if left.prelude.eq_ignore_span(&right.prelude) {
|
||||||
if let Some(left_block) = &left.block {
|
if let Some(left_block) = &mut left.block {
|
||||||
if let Some(right_block) = &right.block {
|
if let Some(right_block) = &mut right.block {
|
||||||
let block = self.merge_simple_block(left_block, right_block);
|
let block = self.merge_simple_block(left_block, right_block);
|
||||||
let mut at_rule = AtRule {
|
let mut at_rule = AtRule {
|
||||||
span: Span::new(
|
span: Span::new(
|
||||||
@ -315,7 +321,7 @@ impl Compressor {
|
|||||||
SyntaxContext::empty(),
|
SyntaxContext::empty(),
|
||||||
),
|
),
|
||||||
name: left.name.clone(),
|
name: left.name.clone(),
|
||||||
prelude: left.prelude.clone(),
|
prelude: left.prelude.take(),
|
||||||
block: Some(block),
|
block: Some(block),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -350,7 +356,7 @@ impl Compressor {
|
|||||||
if self.is_mergeable_at_rule(at_rule)
|
if self.is_mergeable_at_rule(at_rule)
|
||||||
&& matches!(prev_rule, Some(Rule::AtRule(_))) =>
|
&& matches!(prev_rule, Some(Rule::AtRule(_))) =>
|
||||||
{
|
{
|
||||||
if let Some(Rule::AtRule(box prev_rule)) = &prev_rule {
|
if let Some(Rule::AtRule(box prev_rule)) = &mut prev_rule {
|
||||||
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
|
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
|
||||||
*rule = Rule::AtRule(Box::new(at_rule));
|
*rule = Rule::AtRule(Box::new(at_rule));
|
||||||
|
|
||||||
@ -363,7 +369,7 @@ impl Compressor {
|
|||||||
Rule::QualifiedRule(box qualified_rule @ QualifiedRule { .. })
|
Rule::QualifiedRule(box qualified_rule @ QualifiedRule { .. })
|
||||||
if matches!(prev_rule, Some(Rule::QualifiedRule(_))) =>
|
if matches!(prev_rule, Some(Rule::QualifiedRule(_))) =>
|
||||||
{
|
{
|
||||||
if let Some(Rule::QualifiedRule(box prev_rule)) = &prev_rule {
|
if let Some(Rule::QualifiedRule(box prev_rule)) = &mut prev_rule {
|
||||||
if let Some(qualified_rule) =
|
if let Some(qualified_rule) =
|
||||||
self.try_merge_qualified_rules(prev_rule, qualified_rule)
|
self.try_merge_qualified_rules(prev_rule, qualified_rule)
|
||||||
{
|
{
|
||||||
@ -478,7 +484,8 @@ impl Compressor {
|
|||||||
ComponentValue::Rule(box Rule::AtRule(box at_rule @ AtRule { .. }))
|
ComponentValue::Rule(box Rule::AtRule(box at_rule @ AtRule { .. }))
|
||||||
if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) =>
|
if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) =>
|
||||||
{
|
{
|
||||||
if let Some(ComponentValue::Rule(box Rule::AtRule(box prev_rule))) = &prev_rule
|
if let Some(ComponentValue::Rule(box Rule::AtRule(box prev_rule))) =
|
||||||
|
&mut prev_rule
|
||||||
{
|
{
|
||||||
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
|
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
|
||||||
*rule = ComponentValue::Rule(Box::new(Rule::AtRule(Box::new(at_rule))));
|
*rule = ComponentValue::Rule(Box::new(Rule::AtRule(Box::new(at_rule))));
|
||||||
@ -493,7 +500,7 @@ impl Compressor {
|
|||||||
if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) =>
|
if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) =>
|
||||||
{
|
{
|
||||||
if let Some(ComponentValue::StyleBlock(box StyleBlock::AtRule(box prev_rule))) =
|
if let Some(ComponentValue::StyleBlock(box StyleBlock::AtRule(box prev_rule))) =
|
||||||
&prev_rule
|
&mut prev_rule
|
||||||
{
|
{
|
||||||
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
|
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
|
||||||
*rule = ComponentValue::StyleBlock(Box::new(StyleBlock::AtRule(
|
*rule = ComponentValue::StyleBlock(Box::new(StyleBlock::AtRule(
|
||||||
@ -510,7 +517,7 @@ impl Compressor {
|
|||||||
box qualified_rule @ QualifiedRule { .. },
|
box qualified_rule @ QualifiedRule { .. },
|
||||||
)) if prev_rule.is_some() => {
|
)) if prev_rule.is_some() => {
|
||||||
if let Some(ComponentValue::Rule(box Rule::QualifiedRule(box prev_rule))) =
|
if let Some(ComponentValue::Rule(box Rule::QualifiedRule(box prev_rule))) =
|
||||||
&prev_rule
|
&mut prev_rule
|
||||||
{
|
{
|
||||||
if let Some(qualified_rule) =
|
if let Some(qualified_rule) =
|
||||||
self.try_merge_qualified_rules(prev_rule, qualified_rule)
|
self.try_merge_qualified_rules(prev_rule, qualified_rule)
|
||||||
@ -530,7 +537,7 @@ impl Compressor {
|
|||||||
)) if prev_rule.is_some() => {
|
)) if prev_rule.is_some() => {
|
||||||
if let Some(ComponentValue::StyleBlock(box StyleBlock::QualifiedRule(
|
if let Some(ComponentValue::StyleBlock(box StyleBlock::QualifiedRule(
|
||||||
box prev_rule,
|
box prev_rule,
|
||||||
))) = &prev_rule
|
))) = &mut prev_rule
|
||||||
{
|
{
|
||||||
if let Some(qualified_rule) =
|
if let Some(qualified_rule) =
|
||||||
self.try_merge_qualified_rules(prev_rule, qualified_rule)
|
self.try_merge_qualified_rules(prev_rule, qualified_rule)
|
||||||
|
7
crates/swc_css_parser/scripts/instruemnt/bench-lexer.sh
Executable file
7
crates/swc_css_parser/scripts/instruemnt/bench-lexer.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
export RUST_LOG=off
|
||||||
|
export MIMALLOC_SHOW_STATS=1
|
||||||
|
|
||||||
|
cargo profile instruments --release -t time --features swc_common/concurrent --bench lexer -- --bench --color $@
|
@ -4,4 +4,4 @@ set -eu
|
|||||||
export RUST_LOG=off
|
export RUST_LOG=off
|
||||||
export MIMALLOC_SHOW_STATS=1
|
export MIMALLOC_SHOW_STATS=1
|
||||||
|
|
||||||
cargo profile instruments --release -t time --features swc_common/concurrent --bench parser -- --bench --color
|
cargo profile instruments --release -t time --features swc_common/concurrent --bench parser -- --bench --color $@
|
Loading…
Reference in New Issue
Block a user