Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

sassc is very slow to compile and install #189

@eregon

Description

@eregon

When doing a bundle install for a new Rails 6 app, I noticed most of the time is spent compiling sassc (libsass really).

This takes easily up to 2 minutes on Linux, which feels really slow for one gem.
A bit of a Nokogiri-like experience if you see what I mean.
Speaking of Nokogiri, they now have a prerelease gem installing in just 1 second, maybe we can use a similar approach?

$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
$ time gem install sassc                 
Building native extensions. This could take a while...
Successfully installed sassc-2.2.1
1 gem installed
89.75s user 5.43s system 99% cpu 1:36.12 total

I'm not sure what's the best way to address this but here are some ideas:

  • Use the Makefile of libsass to build libsass as a shared library, and just link the C extension to it (as it used to be).
  • Use make parallelism automatically, e.g., by setting MAKEFLAGS
  • Distribute a binary gem on Linux and macOS. This requires having an easy workaround for non-glibc (e.g., alpine) to install from source, or not depending on on glibc (by linking the libc statically?).
  • Changes in libsass so it compiles faster, such as Amalgamate sassc library #132.
  • I thought the -flto might slow things down but actually it seems to speed up compilation with g++ 8.3.1! time gem install sassc -- --disable-lto takes 113.71s user 6.01s system 99% cpu 2:00.70 total.
    Disabling all flags gives: time gem install sassc -- --disable-lto --disable-march-tune-native --disable-static-stdlib => 109.80s user 5.63s system 99% cpu 1:56.12 total.

Use the Makefile of libsass to build libsass as a shared library

That already builds quite a bit faster:

$ time BUILD=shared make       
...
70.53s user 3.94s system 99% cpu 1:14.93 total

I would think the main gain there is that's compiled with -O2:

g++ -Wall -O2 -DLIBSASS_VERSION="3.6.1" -std=c++11 -I /home/eregon/code/libsass/include -fPIC -c -o src/remove_placeholders.o src/remove_placeholders.cpp

instead of (with gem install sassc):

g++ -I. -I/home/eregon/.rubies/ruby-2.6.5/include/ruby-2.6.0/x86_64-linux -I/home/eregon/.rubies/ruby-2.6.5/include/ruby-2.6.0/ruby/backward -I/home/eregon/.rubies/ruby-2.6.5/include/ruby-2.6.0 -I. -I./libsass/include -fPIC -O3 -ggdb3 -std=c++11 -march=native -mtune=native -flto -DLIBSASS_VERSION="3.6.1" -o remove_placeholders.o -c ./libsass/src/remove_placeholders.cpp

We can also parallelize it (I have 4 cores + 4 hyperthreads, i7-7700HQ CPU @ 2.80GHz):

$ time BUILD=shared MAKEFLAGS=-j4 make
81.15s user 4.51s system 387% cpu 22.132 total

That's a reasonable install time!

Using just the MAKEFLAGS approach with gem install is not quite enough:

time MAKEFLAGS=-j4 gem install sassc 
Building native extensions. This could take a while...
Successfully installed sassc-2.2.1
1 gem installed
95.47s user 5.63s system 180% cpu 55.870 total

cc @bolandrm @glebm

Relates to #132

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions