Skip to content

Instantly share code, notes, and snippets.

@KittyGiraudel
Created March 11, 2014 16:04
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KittyGiraudel/9488917 to your computer and use it in GitHub Desktop.
Save KittyGiraudel/9488917 to your computer and use it in GitHub Desktop.
A question regarding Sass & Gzip

About Sass and Gzip

Hey guys! I have a question regarding Sass usage and Gzip compression. If anyone knows something, be sure to share. :)

A quick reminder

It's good practice to use Sass @extend rather than including mixins when possible because of the way Sass handles @extend. To put it simple, it doesn't take the CSS content from the extended selector to place them in the extending one. It works the other way around: it takes the extending selector and append it to the extended selector.

Placeholder

%p { color: red; }
.a { @extend %p; }
.b { @extend %p; }

Output:

.a, .b {
  color: red;
}

Mixin

@mixin m { color: red; }
.a { @include m; }
.b { @include m; }

Output:

.a { color: red; }
.b { color: red; }

The question

Now it is common knowledge that Gzip works best on repeated strings. The more a string is repeated, the better the compression. At least that's what I know from Gzip.

Knowing this, wouldn't it be better for final file size to use mixins rather than placeholders?

I'm applying this question to a Sass context, but that basically can be translated to: is DRY really the best option when it comes to file size?

@lukefrake
Copy link

Sounds like a really interesting challenge, the only thing I would say is you should try and keep file sizes low so that they can cache on mobile. For example I know the iPhone wont cache files that are over 15k.

Would be interested to see if it had an affect on rendering as well, I assume extend would be better for rendering but would be an interesting test.

Lots of interesting thoughts here!

@KittyGiraudel
Copy link
Author

On topic, "Putting the micro in micro-framework" by Ralph Holzmann: http://vimeo.com/34164210. Thanks @paulirish for the heads up! :)

@scottkellum
Copy link

It’s all about authoring style and your preference. I have been leaning towards mixins recently because they can be used more predictably in different contexts and media queries, they don’t add as many selectors that might cause issues in IE, and they can be programmed to output slightly different results.

When I do use extend, it is usually wrapped in a mixin simply for consistency sake. It’s much easier to just write @include everywhere instead of trying to remember if I need to use an extend or a mixin. It is also easier to make changes to abstracted code after it is authored when it is contained in mixins.

@FWeinb
Copy link

FWeinb commented Mar 11, 2014

The gzip size only matters for the delivery over network. The device has to parse the uncompressed file, just keep that in mind too.

I think that something like this:

.a, .b{
  color:red;
}

can be parsed faster than

.a{
 color:red;
}
.b{
 color:red;
}

because in the above style the properties only have to be parsed once. Sure this is an extreme micro optimisation but I just want to point in that direction too.

@vinayraghu
Copy link

Scott, can you share your mixin that you use to extend placeholders? I am very very curious!

Hey Hugo, based on the above comment, I am guessing if they are both the same, then the only difference will be how long it takes to GZip each file. Not the amount of compression. Very curious to see if anyone knows the answer for this!

@KittyGiraudel
Copy link
Author

Scott, can you share your mixin that you use to extend placeholders? I am very very curious!

@mixin a($extend: true) {
  @if $extend {
    @extend %a;
  }
  @else {
    color: red;
  }
}

%a {
  @include a(false);
}

At least that's how I work it.

@Ianfeather
Copy link

I did some profiling on classes vs extends with the theory that classes would gzip better: http://ianfeather.co.uk/object-oriented-sass/#performance

Personally, I wouldn't recommend much about this technique anymore but if it's just filesize you're after there are some comparisons in there.

@scottkellum
Copy link

@rvinay88, @hugogiraudel pretty much got it although I do it with a bit less logic but I really like what he did with that. There is no one mixin, just extending things from within mixins.

@davidtheclark
Copy link

I made a super-contrived little test to at least attach a few numbers to this. (I call it "super-contrived" because as you'll see the code isn't from a real-life-website example, but sort of an idealization of the difference between the two methods.)

I've been accumulating Sass utilities into a library (http://davidtheclark.github.io/scut/index.html) and in that library any mixin for which all variables either are optional or have default values is paired with an extend-placeholder that is the equivalent. For example, @include scut-clearfix is the same as @extend %scut-clearfix because there are no arguments for that one; and @include scut-vcenter-ib (passing no arguments, just taking the default values) is the same as @extend %scut-vcenter-ib.

So what I did was list all the mixins that have equivalent extend-placeholders, then make one file that uses each of those mixins 200 times, and another file that uses each of those extend-placeholders 200 times; then compiled each to CSS; then minified the CSS with grunt-contrib-cssmin with the gzip option on, so it would give a readout of what the filesize would be gzipped.

Here's what the SCSS files looked like: https://gist.github.com/davidtheclark/9999225

And the results were:

File css/test-mixins.min.css created: 700.26 kB → 301.33 kB → 14.69 kB (gzip)
File css/test-extends.min.css created: 142.74 kB → 81.23 kB → 10.16 kB (gzip)

So the mixin version uncompressed was 4.9x bigger; with just minification it was 3.7x bigger; and after GZIP it was only 1.4x bigger.

So it looks from this like GZIP does really significantly cut down on the difference between the efficiency of the two techniques. Also, the artificiality of this test probably magnified the efficiency-difference significantly (the differences between real stylesheets using the occasional mixin or extend would not be nearly so large).

With that in mind, I'm totally in agreement with @scottkellum that, when deciding between equivalent mixins and extends, authoring preferences and maintainability should have more weight than the apparent efficiency of extends -- as long as you're gzipping. And I also agree that mixins are preferable for those reasons.

(Anybody see any problem with this test, any reason it doesn't mean what it seems to me to mean?)

@shayhowe
Copy link

shayhowe commented Mar 9, 2015

For what it's worth, I did some extensive testing on the performance of mixins vs extens across a few different production code bases and have published my results at https://tech.bellycard.com/blog/sass-mixins-vs-extends-the-data/. Hopefully this helps!

@chpio
Copy link

chpio commented Dec 20, 2018

@davidtheclark

Also, the artificiality of this test probably magnified the efficiency-difference significantly (the differences between real stylesheets using the occasional mixin or extend would not be nearly so large).

I don't think so. Gzip works in blocks, so if you use mixins occasionally it wouldn't pick up the duplicates ('cause they are spread over multiple blocks) resulting in even bigger compressed files than your test files (especially if you have used the same mixin multiple times in succession, causing them to land in the same block).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment