dart-scss replaces node-scss

Just today, the official Sass team officially announced that Libsass will be deprecated, as well as Node Sass and SassC based on it, and recommends users to use Dart Sass.

First, let’s take a look at some responses from the official blog (the first half is from the official blog https://sass-lang.com/blog/libsass-is-deprecated), and then we’ll do a benchmark test on Node Sass and Dart Sass. The following questions will be answered after reading this article.

  • So why is there this change?
  • Will Node Sass still be maintained in the future?
  • Does Dart Sass meet our needs?
  • How does Dart Sass perform?
  • The pros and cons of Dart Sass.

Background description

This change comes after extensive discussions among the Sass core team, who concluded that now is the time to officially announce the deprecation of LibSass and packages built on top of it (including Node Sass). Over the years, LibSass apparently did not have enough engineering bandwidth to keep up with the latest developments in the Sass language (for example, the most recent language features were added in November 2018). As much as we’d like to see this situation improve, even the excellent work of long-time LibSass contributors Michael Mifsud and Marcel Greter can’t keep up with the rapid pace of CSS and Sass language development.

It mainly includes the following four points:

  • LibSass is no longer recommended for new Sass projects, use Dart Sass instead.
  • It is recommended that all existing LibSass users make plans to eventually migrate to Dart Sass, and that all Sass libraries make plans to eventually drop support for LibSass.
  • There are no longer plans to add any new features to LibSass, including compatibility with new CSS features.
  • LibSass and Node Sass will be maintained indefinitely on a best-effort basis, including fixing major bugs and security issues and being compatible with the latest Node versions.

Why is it deprecated?

Sass has been in a state of ambiguity for a few years, with LibSass theoretically an officially supported implementation but in practice static in terms of its functionality. As time went on, it became increasingly clear that feeling this state of affairs was causing real problems for Sass users. For example, users are often confused as to why native CSS min() and max() don’t work properly, and may think there’s an issue with Sass overall, but it’s actually because LibSass doesn’t support that functionality.

Officially supported LibSass will not only cause pain to individual users. Since LibSass does not support the Sass module system launched last year, the main related Sass libraries cannot use it due to concerns about incompatibility for its downstream users. It is clearly stated that all Sass users should give up using LibSass. , we hope to make it more practical for authors of these libraries to use more modern features.

LibSass even inhibited the development of the Sass language itself. We can’t move forward with the treating / as a separator proposal because any code they write will produce deprecation warnings in Dart Sass or fail to compile in LibSass. By marking LibSass as deprecated, things will get better, and Sass will get better at supporting the latest versions of CSS.

What does “deprecated” mean?

We chose to use the word “deprecation” because it carries a lot of weight in the programming community and is a strong indication that users should start planning to abandon LibSass. However, that doesn’t mean the project is completely dead. Michael Mifsud, the lead maintainer of LibSass and Node Sass, confirmed that he plans to continue the same level of maintenance as in past years. This means that although no more features will be added (and thus LibSass will slowly drift away from compatibility with the latest CSS and Sass syntax), maintenance releases will continue to be released indefinitely.

What about portability and performance

LibSass has two main advantages over DartSass:

  • Portability: Because it is written in C++, LibSass can be easily embedded in other programming languages and provides a native-feeling API.
  • Performance: Calling LibSass through the C++ API is very fast compared to writing code directly using a scripting language. In particular, this means that LibSass is much faster in JavaScript than Dart Sass’s library compiled to JS (although it is comparable to Dart Sass’s command-line executable).

We are solving both problems using the Sass Embedded Protocol, which runs the Sass compiler as a subprocess and can communicate with any host language via message passing. The embedded protocol supports all the features of the native Sass API, including the ability to define custom importers and Sass functions, while also providing high-performance CLI applications. Dart Sass has implemented the compiler side of the embedded protocol and is actively developing the JavaScript side.

Dart Sass

Dart Sass can be compiled into a sass package written in pure JavaScript and uploaded to npm. The pure JS version is slower than the standalone executable, but is easy to integrate into existing workflows and allows you to define custom functions and importers in JavaScript.

When installed via npm, Dart Sass aims to implement a JavaScript API library that is compatible with Node Sass. Full compatibility is still in development, but Dart Sass currently supports the render() and renderSync() functions. Note, however, that by default, renderSync() is more than twice as fast as render() due to the overhead of asynchronous callbacks.

//Usage example
var sass = require("sass");

sass.render(
  {
    file: scss_filename,
  },
  function(err, result) {
    /* ... */
  }
);

// OR

var result = sass.renderSync({
  file: scss_filename,
});

Benchmark

Test script repository: https://github.com/hua1995116/sass-benchmark

Next, we will test the synchronous and asynchronous performance of Node Sass and Dart Sass respectively.

Test Sass file: https://github.com/ElemeFE/element/blob/dev/packages/theme-chalk/src/date-picker/date-picker.scss

Test model: MacBook Pro (Retina, 15-inch, Mid 2014)

Node version: v12.16.0

Benchmark library: benchmark

speed test

Description: Use benchmark for benchmark testing

result:

sass async x 14.01 ops/sec ±27.72% (55 runs sampled) sass sync x 28.83 ops/sec ±7.24% (63 runs sampled) node-sass async x 47.50 ops/sec ±3.10% (58 runs sampled) Fastest is node -sass async

Note: The larger the value, the faster the speed and the better the performance.

Memory test

Note: The situation after each of the three methods has been operated 50 times.

result:

It can be seen that the performance of Node Sass is indeed very good, which is also an officially mentioned advantage. The performance of Dart Sass’s synchronous method is slightly higher than that of asynchronous method by about 2 times.

Summary

Overall, Dart Sass is future-oriented and supports various new features. The pure JS approach of Dart Sass also frees us from the fear of being dominated by Node Sass compilation. We no longer have to worry about unsuccessful Node Sass installation, and Dart Sass is also actively dealing with its performance issues.