4

I am working on a SPA application built using vue.js 2.6, bootstrap-vue 2.8, sass 1.34 (dart-sass) as preprocessor and sass-loader 10.2.

With the time the project is getting quite big and we've switched from Node-Sass to Dart-Sass (as node-sass is deprecated).

Unfortunately, we're now getting performance issues when building or developping on the project, as it now takes approximately 15 minutes to create a new built, and we're often encountering high memory usage in development.

After reading this article, I figure out using the speed-measure-webpack-plugin that 95% of the compilation time is due to css compilation purposes as most of the SMP stacktrace contains such several entries:

mini-css-extract-plugin, and 
css-loader, and 
vue-loader, and 
postcss-loader, and 
sass-loader, and 
cache-loader, and 
vue-loader took 2 mins, 40.68 secs

Removing the bootstrap imports on the main app.scss file really improve performance, and totally removing the sass compilation removes 95% of the time spent.

Reading this page on dart-sass Github, I understood that the dart Sass native executable is more powerful than the dart sass on node.js version.

Here is my vue.config.js:

process.env.VUE_APP_VERSION = require('./package.json').version
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')

module.exports = {
  runtimeCompiler: true,
  devServer: {
    disableHostCheck: true
  },
  css: {
    loaderOptions: {
      scss: {
        implementation: require('sass'), // This line must in sass option
        additionalData: `@import "@/assets/scss/app.scss";`
      }
    }
  },
  chainWebpack: config => {
    config.module
      .rule('eslint')
      .use('eslint-loader')
      .options({
        fix: false
      })

    config.plugin('speed-measure-webpack-plugin')
      .use(SpeedMeasurePlugin)
      .end()
  }
}

If I've well understand, using this configuration the Dart Sass on Node.js is used during compilation.

I've setup the dart-sass standalone version from this page and I can execute it on the command line, but I don't actually know if it's possible to run it in the webpack compilation instead of the Node.js version ? I've searched on the vue.js, webpack and sass-loader documentations but without success.

EDIT:

The compilation time issue described in this post was due to the import of a file containing the css of the whole app in additionalData (additionalData: @import "@/assets/scss/app.scss";). We did this to use Bootstrap variables in several components but it's clearly not the good way to do it. If you wish to use bootstrap variables in vue components the best option might be to import a file containing your custom and bootstrap variables on every components requiring it, like:

<style lang="scss" scoped>
@import '@/assets/scss/bootstrap';
</style>
pierreben
  • 239
  • 3
  • 12
  • 2
    Are you using `fibers` package as recommended in `sass-loader` [docs](https://github.com/webpack-contrib/sass-loader) ? – Michal Levý May 26 '21 at 14:07
  • 15 minutes is awful. What is the content of `app.scss` ? If it is included in every style compilation (thanks to `additionalData`), it should contain only maybe few variables. The note about removing bootstrap imports from it sounds worrying ... – Michal Levý May 26 '21 at 14:15
  • @MichalLevý, yes I am using fibers. The app.scss contains several external and internal modules css/scss files like so: `@import '~bootstrap/scss/bootstrap';` `@import '~bootstrap-vue/src/index';` `@import '~vue-multiselect/dist/vue-multiselect.min.css';` `@import '~mapbox-gl/dist/mapbox-gl.css';` `@import '~flatpickr/dist/flatpickr.css';` `@import '~vue-swatches/dist/vue-swatches.min.css';` `@import '~vue-select/dist/vue-select.css';` – pierreben May 26 '21 at 15:03

1 Answers1

2

Using Dart VM from webpack/sass-loader is probably not possible

I had a feeling (confirmed by comments) that you are including too much with additionalData: '@import "@/assets/scss/app.scss";'

additionalData is pre-pended to any style compilation - which in case of Vue + sass-loader means that everything inside @/assets/scss/app.scss is compiled every time there is a <style> block inside Vue SFC (as each <style> block is compiled separately)

additionalData is useful for variables you need inside most of the components. Things such primary color, text sizes etc. NOT to include some global/dependency styles!

Just move most of the SASS/CSS imports to your main.js or App.vue or simply remove additionalData and your app build time will improve considerably...

Michal Levý
  • 33,064
  • 4
  • 68
  • 86
  • 1
    Many thanks, you're totally right, I've replaced the file included in additionalData with standalone bootstrap variables import in the components requiring it and the compilation time reduced from 15 min to 1 min. And I noticed that it is not possible to use Dart sass VM with webpack. – pierreben May 26 '21 at 16:48
  • @pierreben Cool. I bet this is much better improvement than the use of native dart-sass would give you. Please consider marking this as an answer instead of editing your question to describe the same thing I did.. – Michal Levý May 26 '21 at 17:13