简体   繁体   中英

Less compiling slow with Grunt

I'm wanting to move over to Grunt to perform my LESS compiling.

My LESS files are split up into about 117 files. I've got about 170 imports in total as code is shared between the admin and member areas of my project.

I was using LiveReload and it is compiling LESS in about 500 - 700ms. Once the browser live reloads, it's about 2 seconds in total to see the result.

Grunt takes 1.8 seconds to compile, so once the browser live reloads, it's about 4 seconds in total.

Grunt is significantly slower.

I am testing on an iMac with an i7 CPU, SSD and 16GB RAM. I am running Grunt locally and not inside a VM.

My questions are this:

  1. Are all the LESS imports and files slowing it down?
  2. Is Grunt just slower in general?

My package.json file:

{
  "name": "Test Package",
  "version": "1.0.0",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-less": "*"
  },
  "dependencies": {
    "time-grunt": "*"
  }
}

And my Gruntfile.js:

module.exports = function(grunt) {

  // Measures the time each task takes
  require('time-grunt')(grunt);

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    less: {
      all: {
            files: {
              "css/style.css": "less/style.less",
              "css/admin/style.css": "less/admin/style.less",
              "css/admin/spectrum/spectrum.css": "less/plugins/spectrum/spectrum.less"
            },
          }
        }
  });

  // Load the plugins
  grunt.loadNpmTasks('grunt-contrib-less');

  // Default task(s).
  grunt.registerTask('default', ['less']);

};

Any suggestions on how I can format my code to compile much faster? Or is this a limitation of this library at the moment?

I guess that 500-700ms to compile 170 files is pretty reasonable.

This answer does not provide you with a fully functional gruntfile but you should be able to incorporate these suggestions and improve your workflow.

First thing: is it necessary to compile all the files at once? You might want to split the less task in 2 sections instead of all : one for the admin and one for the members area (supposing you are not working on both sections at the same time). Something like:

less: {
        members: {
            options: {
                compress: true //maybe
            },
            files: {
                "app/members.css": "members.less"
            }
        },
        admin: {
            options: {
                compress: true //maybe
            },
            files: {
                "app/admin.css": "admin.less"
            }
        },
    }

Of course, you can divide the sections even more based on your project structure.

Then you create 2 or more grunt tasks to compile selectively:

grunt.registerTask('a', ['less:admin']); //let's call it 'a' - from admin
grunt.registerTask('m', ['less:members']); // 'm' for members

and you run grunt a or grunt m based on what you need to compile. This should speed up the overall compile time.

I use a different approach, however:

  • I use a watch task to look for modified .less files
  • on watch .less file changed, I only do a compile and not a liveReload. In watch config I have this section:

     less: { options: { livereload: false }, files: 'blah-blah.less', //use your paths here tasks: ['less:dev'] //less:members or less:admin in your case } 
  • once the less compilation is done we have an updated .css file which triggers again the watch on css files. Again, in watch config I have this section:

     css: { files: ['blah-blah.css'], //the .css file resulted from compilation options: { livereload: true, //this is the most important spawn: false //you may also need this }, } 
  • I have a grunt watch task that looks for changes in the folder I specified. Something like this:

     grunt.registerTask('watch', ['other tasks', 'connect', 'watch']); 

    Note that I also use connect to run a small http server but it may not be the case here.

Now, what happens is this:

  • before starting development I run grunt watch . It starts the server and it looks for file changes on .less files
  • whenever a .less file is changed it gets compiled and the .css file gets updated. Note that the browser does not refresh yet
  • when the .css file gets changed the browser does refresh but without loading the entire html, only applying the resulted stylesheet.

So, if you make a change in any .less file in no time you will see it reflected in your browser without reloading the entire page , saving you other seconds as well.

This way you also avoid the 2sec grunt compilation time when you want to compile the .less files because grunt is already running.

In my case the compilation was also slow but I used timer-grunt (like you do) and found out that most wasted time was on loading dependencies so I used jit-grunt to load them on demand, but this is another story. You can see it in this thread .

Now, coming back to your questions:

  1. Are all the LESS imports and files slowing it down?

Depends on how many files, how big they are, if you compile them altogether. I don't think it's the case here if you split them in several smaller tasks.

  1. Is Grunt just slower in general?

Not in this case, I guess you are not using an optimum workflow. Grunt's speed vs. gulp is another debate, maybe while having a few beers. And BTW, this library is not as limited as you may think ;)

Anyway, if you follow the steps above I think you will get an awesome improvement in speed.

Hope this helps others as well!

If anyone has a different opinion or other strategies, please share. I am always eager to improve my workflows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM