2

I am running my Angular app with grunt serve for local dev, and if I inspect an element and try to adjust the styles in the browser using Chrome dev tools everything becomes very laggy and unusable. I've tried to do research about this problem, but I can't find anything helpful. Anyone have any ideas?

EDIT: I used generator-angular-ui-router to generate my project, and it's possible something is just messed up in my Gruntfile from that because I don't believe I have experienced this issue before using grunt.

In response to a request for my Gruntfile, here it is:

// Generated on 2014-09-04 using generator-angular 0.9.7
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Configurable paths for the application
  var appConfig = {
    app: require('./bower.json').appPath || 'app',
    dist: 'dist'
  };

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: appConfig,

// Watches files for changes and runs tasks based on the changed files
watch: {
  bower: {
    files: ['bower.json'],
    tasks: ['wiredep']
  },
  js: {
    files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
    tasks: ['newer:jshint:all'],
    options: {
      livereload: '<%= connect.options.livereload %>'
    }
  },
  jsTest: {
    files: ['test/spec/{,*/}*.js'],
    tasks: ['newer:jshint:test', 'karma']
  },
  compass: {
    files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
    tasks: ['compass:server', 'autoprefixer']
  },
  gruntfile: {
    files: ['Gruntfile.js']
  },
  livereload: {
    options: {
      livereload: '<%= connect.options.livereload %>'
    },
    files: [
      '<%= yeoman.app %>/{,*/}*.html',
      '.tmp/styles/{,*/}*.css',
      '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
    ]
  }
},

// The actual grunt server settings
connect: {
  options: {
    port: 9000,
    // Change this to '0.0.0.0' to access the server from outside.
    hostname: 'localhost',
    livereload: 35729
  },
  livereload: {
    options: {
      open: true,
      base: [
        '.tmp',
        '<%= yeoman.app %>'
      ]
    }
  },
  test: {
    options: {
      port: 9001,
      base: [
        '.tmp',
        'test',
        '<%= yeoman.app %>'
      ]
    }
  },
  dist: {
    options: {
      open: true,
      base: '<%= yeoman.dist %>'
    }
  }
},

// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
  options: {
    force: false,
    jshintrc: '.jshintrc',
    reporter: require('jshint-stylish')
  },
  all: {
    src: [
      'Gruntfile.js',
      '<%= yeoman.app %>/scripts/{,*/}*.js'
    ]
  },
  test: {
    options: {
      jshintrc: 'test/.jshintrc'
    },
    src: ['test/spec/{,*/}*.js']
  }
},

// Empties folders to start fresh
clean: {
  dist: {
    files: [
      {
        dot: true,
        src: [
          '.tmp',
          '<%= yeoman.dist %>/{,*/}*',
          '!<%= yeoman.dist %>/.git*'
        ]
      }
    ]
  },
  server: '.tmp'
},

// Add vendor prefixed styles
autoprefixer: {
  options: {
    browsers: ['last 1 version']
  },
  dist: {
    files: [
      {
        expand: true,
        cwd: '.tmp/styles/',
        src: '{,*/}*.css',
        dest: '.tmp/styles/'
      }
    ]
  }
},

// Automatically inject Bower components into the app
wiredep: {
  options: {
    //cwd: '<%= yeoman.app %>'
  },
  app: {
    src: ['<%= yeoman.app %>/index.html'],
    ignorePath: /\.\.\//
  },
  sass: {
    src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
    ignorePath: /(\.\.\/){1,2}bower_components\//
  }
},

// Compiles Sass to CSS and generates necessary files if requested
compass: {
  options: {
    sassDir: '<%= yeoman.app %>/styles',
    cssDir: '.tmp/styles',
    generatedImagesDir: '.tmp/images/generated',
    imagesDir: '<%= yeoman.app %>/images',
    javascriptsDir: '<%= yeoman.app %>/scripts',
    fontsDir: '<%= yeoman.app %>/styles/fonts',
    importPath: '<%= yeoman.app %>/bower_components',
    httpImagesPath: '/images',
    httpGeneratedImagesPath: '/images/generated',
    httpFontsPath: '/styles/fonts',
    relativeAssets: false,
    assetCacheBuster: false,
    raw: 'Sass::Script::Number.precision = 10\n'
  },
  dist: {
    options: {
      generatedImagesDir: '<%= yeoman.dist %>/images/generated'
    }
  },
  server: {
    options: {
      debugInfo: true
    }
  }
},

// Renames files for browser caching purposes
filerev: {
  dist: {
    src: [
      '<%= yeoman.dist %>/scripts/{,*/}*.js',
      '<%= yeoman.dist %>/styles/{,*/}*.css',
      '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
      '<%= yeoman.dist %>/styles/fonts/*/.{eot,svg,ttf,woff,woff2}'
    ]
  }
},

// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
  html: '<%= yeoman.app %>/index.html',
  options: {
    dest: '<%= yeoman.dist %>',
    flow: {
      html: {
        steps: {
          js: ['concat', 'uglifyjs'],
          css: ['cssmin']
        },
        post: {}
      }
    }
  }
},

// Performs rewrites based on filerev and the useminPrepare configuration
usemin: {
  html: ['<%= yeoman.dist %>/{,*/}*.html'],
  css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
  options: {
    assetsDirs: ['<%= yeoman.dist %>', '<%= yeoman.dist %>/images']
  }
},

// The following *-min tasks will produce minified files in the dist folder
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
// cssmin: {
//   dist: {
//     files: {
//       '<%= yeoman.dist %>/styles/main.css': [
//         '.tmp/styles/{,*/}*.css'
//       ]
//     }
//   }
// },
// uglify: {
//   dist: {
//     files: {
//       '<%= yeoman.dist %>/scripts/scripts.js': [
//         '<%= yeoman.dist %>/scripts/scripts.js'
//       ]
//     }
//   }
// },
// concat: {
//   dist: {}
// },

imagemin: {
  dist: {
    files: [
      {
        expand: true,
        cwd: '<%= yeoman.app %>/images',
        src: '{,*/}*.{png,jpg,jpeg,gif}',
        dest: '<%= yeoman.dist %>/images'
      }
    ]
  }
},

svgmin: {
  dist: {
    files: [
      {
        expand: true,
        cwd: '<%= yeoman.app %>/images',
        src: '{,*/}*.svg',
        dest: '<%= yeoman.dist %>/images'
      }
    ]
  }
},

htmlmin: {
  dist: {
    options: {
      collapseWhitespace: true,
      conservativeCollapse: true,
      collapseBooleanAttributes: true,
      removeCommentsFromCDATA: true,
      removeOptionalTags: true
    },
    files: [
      {
        expand: true,
        cwd: '<%= yeoman.dist %>',
        src: ['*.html', 'views/{,*/}*.html'],
        dest: '<%= yeoman.dist %>'
      }
    ]
  }
},

// ng-annotate tries to make the code safe for minification automatically
// by using the Angular long form for dependency injection.
ngAnnotate: {
  dist: {
    files: [
      {
        expand: true,
        cwd: '.tmp/concat/scripts',
        src: ['*.js', '!oldieshim.js'],
        dest: '.tmp/concat/scripts'
      }
    ]
  }
},

// Replace Google CDN references
cdnify: {
  dist: {
    html: ['<%= yeoman.dist %>/*.html']
  }
},

// Copies remaining files to places other tasks can use
copy: {
  dist: {
    files: [
      {
        expand: true,
        dot: true,
        cwd: '<%= yeoman.app %>',
        dest: '<%= yeoman.dist %>',
        src: [
          '*.{ico,png,txt}',
          '.htaccess',
          '*.html',
          'views/{,*/}*.html',
          'images/{,*/}*.{webp}',
          'htmlImages/**',
          'headerResources/**',
          'styles/fonts/**'
        ]
      },
      {
        expand: true,
        cwd: '.tmp/images',
        dest: '<%= yeoman.dist %>/images',
        src: ['generated/*']
      },
      {
        expand: true,
        dot: true,
        cwd: '<%= yeoman.app %>/bower_components/font-awesome',
        src: ['fonts/*.*'],
        dest: '<%= yeoman.dist %>'
      }
    ]
  },
  styles: {
    expand: true,
    cwd: '<%= yeoman.app %>/styles',
    dest: '.tmp/styles/',
    src: '{,*/}*.css'
  }
},

// Run some tasks in parallel to speed up the build process
concurrent: {
  server: [
    'compass:server'
  ],
  test: [
    'compass'
  ],
  dist: [
    'compass:dist',
    'imagemin',
    'svgmin'
  ]
},

// Test settings
karma: {
  unit: {
    configFile: 'karma.conf.js',
    singleRun: true
  }
},

ngconstant: {
  // Options for all targets
  options: {
    space: '  ',
    wrap: '\'use strict\';\n\n {%= __ngModule %}',
    name: 'config'
  },
  // Environment targets
  development: {
    options: {
      dest: '<%= yeoman.app %>/scripts/config.js'
    },
    constants: {
      ENV: {
        name: 'development',
        apiEndpoint: 'http://localhost:3026/api'
      }
    }
  },
  production: {
    options: {
      dest: '<%= yeoman.app %>/scripts/config.js'
    },
    constants: {
      ENV: {
        name: 'production',
        apiEndpoint: 'http://predictagram.com:3026/api'
      }
    }
  }
}
  });


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

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

  grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run(['serve:' + target]);
  });

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

grunt.registerTask('build', [
'clean:dist',
'ngconstant:production',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);

grunt.registerTask('default', [
'newer:jshint',
'test',
'build'
  ]);
};
rwwagner90
  • 360
  • 3
  • 16
  • Could you share your Gruntfile , as without code is very difficult to debug. Also more the number of tasks that you have in Grunt , higher the chances of slowdown in build process. – Prayag Verma Jan 14 '15 at 18:00
  • I just added my Gruntfile – rwwagner90 Jan 14 '15 at 22:26
  • Do I need to do anything else to help figure this out? Let me know. The issue is not the slow build, I expect that. It's when running grunt serve and inspecting an element, it's so slow to inspect. – rwwagner90 Jan 16 '15 at 17:39
  • Can you try with watch disabled in your serve task. Just comment the `watch` in `grunt.registerTask('serve', ...` – Vishwanath Jan 19 '15 at 13:02
  • 1
    Try removing livereload section and test section (one at a time), in order to try and isolate the root cause. It is difficult to answer without a code/demo – Yaniv Efraim Jan 19 '15 at 17:00
  • I think you should try using [jit-grunt](https://www.npmjs.com/package/jit-grunt) instead of load grunt tasks. It would also help to see the timing logs of the tasks from your console in a gist. – JaKXz Jan 21 '15 at 04:25

1 Answers1

2

I think the main problem is coming from the gem Compass, as she is slow to compile the SASS every time you made a change, so you can try to update the gem Compass.

gem update compass

and can you show your compass & ruby version please.

gem list compass

ruby -v

also you can check this post :

Grunt LiveReload is really slow

As I don't know how your CSS is delivered to your Chrome browser.

If it's only about editing in Chrome maybe it's coming from a setting in Chrome ?

http://benfrain.com/test-your-sass-or-css-with-the-chrome-developer-tools/

Or try with Chrome Canary or Firefox Developer version :

https://www.google.fr/chrome/browser/canary.html

https://www.mozilla.org/fr/firefox/developer/

How many lines does your compiled CSS have ?

Community
  • 1
  • 1
rbinsztock
  • 3,025
  • 2
  • 21
  • 34
  • This is not what I am looking for. I am not editing the sass and causing a recompile, I am editing the styles inline, in the browser, which should have nothing to do with compiling the sass. – rwwagner90 Jan 21 '15 at 19:32
  • Chrome canary does not have the issue. Weird. – rwwagner90 Jan 22 '15 at 17:56