Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grunt tasks are slow in yeoman application

I have an angular project build with yeoman, talking to a rails api backend.

Everything works fine, except that grunt tasks are very slow.

When I run grunt server --verbose:

Execution Time (2014-01-15 13:37:55 UTC)
loading tasks         14.3s  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 26%
server                  1ms  0%
preprocess:multifile   11ms  0%
clean:server           13ms  0%
concurrent:server     34.3s  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 63%
autoprefixer            1ms  0%
autoprefixer:dist     369ms  ▇ 1%
connect:livereload     17ms  0%
watch                  5.8s  ▇▇▇▇▇▇▇▇▇ 11%
Total 54.8s

Some of my Gruntfile:

'use strict';
module.exports = function (grunt) {
  require('time-grunt')(grunt);
  require('load-grunt-tasks')(grunt);
  require('time-grunt')(grunt);

  grunt.initConfig({
    ...
  });

grunt.loadNpmTasks('grunt-preprocess');

  grunt.registerTask('server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'preprocess:multifile',
      'clean:server',
      'concurrent:server',
      'autoprefixer',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'autoprefixer',
    'connect:test'
    //'karma'
  ]);

  grunt.registerTask('build', [
    'preprocess:multifile',
    'clean:dist',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'copy:dist',
    'cdnify',
    'ngmin',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
  ]);

  grunt.registerTask('default', [
    'jshint',
    'test',
    'build'
  ]);

};

Size of project:

vagrant@vm ~code/myapp/app/scripts
$> find -name "*.js" | xargs cat | wc -l
10209

I am running on MacOS 10.8 with i7 processor, 16GB ram, SSD... It is normal that is takes so long ? What makes the grunt task (and especially "loading tasks") so slow ?

Note: I am ssh'd inside a vagrant machine and running the grunt commands from there. If I run the grunt command on my native system, it's much faster (loading tasks takes 1.6s instead of 14.3).

So the shared filesystem might be an issue. But why...

like image 375
Benjamin Crouzier Avatar asked Jan 15 '14 13:01

Benjamin Crouzier


4 Answers

I had exactly same problem with Vagrant and Yeomans angular-generator. After running grunt serve it took almost 30 seconds to compile sass, restart server etc.

I already used NFS but it was still slow. Then I tried jit-grunt, just-in-time grunt loader. I replaced load-grunt-tasks with jit-grunt and everything is now a lot faster.

Here's a good article about JIT-Grunt: https://medium.com/written-in-code/ced193c2900b

like image 131
valstu Avatar answered Oct 12 '22 15:10

valstu


I am using grunt inside a Vagrant virtualbox. (ubuntu 12.04). My native files are on my host machine (OSx). Because the grunt tasks are io-intensive, and they are run through file sharing, this make them quite slow.

This can be improved by adding nfs to Vagrant (http://docs.vagrantup.com/v2/synced-folders/nfs.html). This will make Vagrant share files with nfs instead of the default Vagrant file sharing. It will be a bit faster, but not much.

For comparison, on my machine:

For running the subtask loading grunt tasks

  • natively: 1.2s
  • with nfs: 4s
  • vagrant file sharing: 16s

If only a specific task is taking a lot of time, this specific task might be the problem. To troubleshoot, use time-grunt: https://npmjs.org/package/time-grunt.

like image 31
Benjamin Crouzier Avatar answered Oct 12 '22 16:10

Benjamin Crouzier


I've had issues as well, and have found:

nospawn: true

To be the fastest option. I went from ~20s to ~1s to concat, minify, and uglify JS.

like image 2
Cameron Avatar answered Oct 12 '22 15:10

Cameron


I had the same problem with Yeoman's ngbp generator and Vagrant. Even with nfs, a simple change on a template took about 30s to be seen in the browser.

Using jit-grunt caused time to be reduced to 10s. After using spawn:false, even though there was no reduction at the first load, changes took less than 1s (0.086s) to propagate to the browser! (Yes!)

The changes I've made to Gruntfile.js:

  1. I commented all the grunt.loadNpmTasks but grunt.loadNpmTasks('grunt-contrib-watch') [That's because of a task rename ngbp does later on];
  2. I added require('jit-grunt')(grunt); after grunt.loadNpmTasks('grunt-contrib-watch');
  3. I added spawn: false to delta: { options: {livereload: true, spawn: false} ...}.
like image 2
danilogbotelho Avatar answered Oct 12 '22 16:10

danilogbotelho