Does SASS Harm Performance

Does sass harm performance?

You have to find your compromise between maintainability (nesting makes it easier to find your way around in the stylesheet) and rendering performance.

A rule of thumb says you should try to restrict yourself to a three-level nesting and you should avoid to nest IDs if it's not necessary.

However, I think nesting too much is not the biggest issue. As soon as I became aware of the power of mixins, I used them a lot.

For example, this is my often used button mixin:

@mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
display: inline-block
padding: 4px 10px
right: 10px
bottom: 10px
border: none
background-color: $button-color
color: $font-color-inv
+sans-serif-font(9px, 700)
text-align: center
text-transform: uppercase
cursor: pointer
@if $shadow
text-decoration: none
background-color: $hover-color
margin-right: 0
color: $font-color-inv
&, &:hover
text-decoration: none
background-color: $button-color
background-color: $active-color
background-color: $active-color

You see, quite a bit code. Applying such mixins to many elements on your page will result in a big CSS file which takes longer to be interpreted.

In the old fashioned CSS-way you would give each button element e.g. the class .small-button. But this method pollutes your markup with unsemantic classes.

Sass provides a solution though: selector inheritance via the @extend directive.

If you set defaults for your parameter of the mixin, you can also provide a simple class, which uses the mixins with your default:

// Use this mixin via @extend if you are fine with the parameter defaults

And then you can just inherit from this class in various contexts:

@extend .small-button

The resulting CSS statement aggregates all usages of .small button into one rule with comma-separated selectors:

.small-button, #admin-interface input[type=submit] {
display: inline-block;

Concluding, a naive usage of Sass can effect your CSS performance. Used wisely, however, it is maintainable thanks to well-structured and DRY code, it leads to proper separation of markup and styling (semantic classes only) and allows for smart and performant CSS code.

Performance of using LESS and SASS

LESS and SASS both make CSS easier to write and manage due to powerful features like functions, variables and mixins, but since they compile down to CSS before deployment they don't affect performance in the slightest. Your performance is based solely on the CSS output which can be minified just well.

You CAN have the LESS run at the client using a javascript interpreter like less.js, but I've yet to see a good reason to do so. It's both slower (obviously), and almost certainly larger due to the javascript library requirement.

How bad is it in practice to over-nest selectors in SASS/SCSS?

It depends on how much dynamic manipulation of the DOM and styles will go on after page load. It's not page loads (mostly) or slow selectors on initial layout that are at issue, it's repaints/reflows.

Now, Steve Souders says that on the average site it's simply not a real concern. However, on a web app or highly interactive site, poorly performing CSS rules can make your repaints slower than they have to be. If you have a lot of repaints...

Experts such as Nicole Sullivan, Paul Irish, and Steve Souders have covered the way CSS interacts with with JavaScript and how to write highly performant CSS selectors. It's more than depth (different selectors have different performance), but a good rule of thumb is to limit both depth and complexity to keep yourself out of trouble--but not so much performance trouble, read on.

However, as notes, it's not so much descendant or specific selectors as it is certain properties in certain contexts ( that make paints expensive. I see long or complicated selectors more as a maintainability issue (Nicolas Gallagher) than a performance issue--keeping in mind that maintainability interacts with performance. Highly maintainable code can iterate faster and is easier to debug (helping you find and fix performance issues).

Now, as to Sass optimization. Yes, Sass can optimize your CSS. But it cannot optimize your selectors. A 4 level nested block will be output as a 4 level nested selector. Sass cannot change it without possibly making your CSS not work. You, as the author, have to optimize the way you write Sass to optimize your output. I, personally, use nesting only in a limited way (a killer feature in Sass for me is composing styles with @extend and placeholders). However, if you really love nesting you might be able to tweak your output to some degree using the Sass parent selector reference (or the newer @at-root).

So far as I know, neither Sass nor Compass has a built-in tool to analyze selectors and warn about them. It's probably possible to create a tool to do that (set a max depth and have your pre-processor warn you) utilizing an AST. More directly, Google Page Speed does have an existing feature that provides some information. SCSS Lint has a nesting option. There's also CSS Lint. (These can theoretically be added to run in your Compass config's on_stylesheet_saved if you're not already using something like Grunt or Gulp).

sass nesting at 2 levels

It depends on what you mean by "efficient"—if you are referring to the efficiency of the compiled CSS code, both of your examples are equivalent; they both compile down to the same CSS.

If you are referring to developer efficiency, in my opinion the first example is more readable and maintainable (one of the nice features of Sass is the ability to nest media queries in context, which is what you are doing). Your example 1 is usually the approach I take.

So, in answer to your questions:

  1. This is a perfectly acceptable method.
  2. No.

Does a trailing plus sign on the left make sense in SASS

While valid, adding an ampersand before the combinators is not necessary at all. The ampersand is only needed for attribute selectors, pseudo classes, and pseudo elements, because the real difference between those using & and those not (in theory) is the space in the output. Here's a good article on this.

CSS performance with respect to inheritance

I think that the MDN article you showed is written in a harmful way, as it proposes to focus on CSS micro-optimizations while almost always page speed can be increased in different ways (eg. Google Page Speed has interesting hints).

I can't remember any situation in my websites where CSS was a bottleneck. You might want to see "Timeline" in Chrome Developer Tools on some pages and notice that the amount of time spent on working with styles is usually insignificant compared to other events.

If I was to give advice, I'd rather go the other way and use CSS preprocessing tools like SASS or LESS to improve maintainability. This might even eventually help to reduce number of rules.

Efficient SASS for loops

Use @extend inside your loop to group different rules with same values.

text-align: left;

@for $i from 1 through 50 {
td, th, /* deep */ th {
@extend %text-left;

Apply style to multiple selectors or use multiple classes. Which has better performance?

I too had this question and after some research I found a post about CSS Rendering Speed - Grouping Selectors vs Properties on Forrst.

While the author compares the difference between grouping selectors vs properties in the CSS, I wanted to know if it were faster to apply styles using multiple classes on the elements… so I made a test, the author ran it, turns out it is faster to use multiple classes in your html:

                                   1k      10k
Grouping Selectors layout time ~12ms ~110ms
Grouping Properties layout time ~12ms ~117ms
Object Oriented CSS layout time ~11ms ~112ms

Grouping Selectors DOM ready ~50ms ~405ms
Grouping Properties DOM ready ~64ms ~640ms
Object Oriented CSS DOM ready ~47ms ~349ms

Grouping Selectors file size 55kb 563kb
Grouping Properties file size 93kb 943kb
Object Oriented CSS file size 64kb 633kb

Additionally when you use more classes in the markup your code will be more readable, predictable, maintainable, scaleable, etc. When you read the following code, you know that this item is an icon and that it's also a checkmark icon.

<div class="icon icon-checkmark"></div>

This code also allows for easy selection of all "icon" elements with JavaScript.

Overloading the styles on a class will limit the ways in which you can use the class.

All said, since the actual browser render time delta is negligible, optimization at this level should be focused on saving developer time.

The answers here are quite sound too: CSS - Multiple vs Single class on an element

Related Topics

Leave a reply