CSS performance - to group or not to group?

526 views Asked by At

I was wondering what impact on parsing and rendering performance may have to group rules in CSS.

Approach 1:

.class1 {
  margin: 10px;
  padding: 20px;
  color: #ccc;
}
.class2 {
  margin: 10px;
  padding: 30px;
  color: #ddd;
}
.class3 {
  margin: 20px;
  padding: 30px;
  color: #eee;
}
.class4 {
  margin: 20px;
  padding: 20px;
  color: #fff;
}

vs approach2:

.class1,
.class2 {
  margin: 10px;
}
.class3,
.class4 {
  margin: 20px;
}
.class1,
.class4 {
  padding: 20px;
}
.class2,
.class3 {
  padding: 30px;
}
.class1 {
  color: #ccc;
}
.class2 {
  color: #ddd;
}
.class3 {
  color: #eee;
}
.class4 {
  color: #fff;
}

Of course, we are talking about large css files with same rules grouping, so the same selector is fragmented into plenty of chunks sometimes.

Does it impact css parsing and rendering significantly enough to abandon this approach in favour of bigger file, but cleaner and gathering all rules in one selector?

Selector matching may be expensive. In real life case, each of those selectors is not just one class, but 2-3 nested classes. So for each element browser has to match selector three times to apply all rules. First for margin, then for padding, then apply color. The second approach seems very expensive.

3

There are 3 answers

2
Salman Ahmed On

Group. This makes your CSS file neat and clear. It improve your rendering performance too. Writing same things again and again is not a good practice.

1
PerniCZek On

If you have the same property in the project in many places, add the class. Or group.

1
kali187 On

I've prepared two codepens with two options:

Approach 1 (one selector per class) - https://codepen.io/kali187/pen/EvpVdb - (just output: https://codepen.io/kali187/live/EvpVdb )

@for $n from 1 through 2000 {
  .div-#{$n} {
      float: left;
      background: rgb( $n, $n, $n );
      height: 10px + 1px * $n / 2;
      width: 20px + 1px * $n / 5;
      margin: 0 1px 1px 0;
      border: 1px solid #f00;
  }
}

Approach 2 (multiple selectors for one class) - https://codepen.io/kali187/pen/dzjGPa - (just output: https://codepen.io/kali187/live/dzjGPa )

$max: 1000;

@for $i from 1 through $max {
  %bg-#{$i} {
    background: rgb( $i, $i, $i );
  }
  %width-#{$i} {
    width: 20px + 1px * ceil($i / 5);
  }
  %height-#{$i} {
    height: 20px + 1px * ceil($i / 3);
  }
}

@for $n from 1 through (2*$max) {
  .div-#{$n} {
      float: left;
      @extend %bg-#{ceil($n/2)};
      @extend %width-#{ceil($n/3)};
      @extend %height-#{ceil($n/4)};
      margin: 0 1px 1px 0;
      border: 1px solid #f00;
  }
}

Results of rendering for the first approach: enter image description here Parsing styles and html ~ 25ms

Results of rendering for the second approach: enter image description here Parsing styles and html ~ 75ms (3 times that long)

If anyone would like to test it, please do