grunt-contrib-watch
grunt-contrib-watch copied to clipboard
High CPU usage
Hi, Grunt Watch consumes about 65-70% CPU Resources.
my devDependencies are as follows.
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-uglify": "^0.9.1",
"grunt-contrib-watch": "^0.6.1",
"grunt-sass": "^0.18.1",
"load-grunt-tasks": "^3.1.0",
"node-bourbon": "^4.2.1-beta1"
}
my gruntfile:
var path = "C:/gdrive/apps/3oak/wp-content/themes/3flooring/";
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt); // npm install --save-dev load-grunt-tasks
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Watch ===========
watch: {
// Sass -----
sass: {
files: [
path + 'components/sass/*.{scss,sass}',
path + 'components/sass/styles/*.{scss,sass}',
path + 'components/sass/styles/custom/*.{scss,sass}',
path + 'components/sass/styles/custom/**/*.{scss,sass}'
],
tasks: ['sass']
},
// Reload -
livereload: {
files: [
path + '*.php',
path + '**/*.php',
path + '**/**/*.php',
path + 'js/*.{js,json}',
path + 'js/**/*.{js,json}',
path + 'components/sass/*.{scss,sass}',
path + 'components/sass/**/*.{scss,sass}',
path + 'components/sass/**/**/*.{scss,sass}'],
options: {
livereload: true
}
},
// Scripts -
scripts: {
files: [
path + 'components/js/*.{js,json}'
],
tasks: ['uglify']
}, // scripts
},
sass: {
dist: {
options: {
sourceMap: true,
includePaths: [
require('node-bourbon').includePaths,
path + 'components/sass/*.{scss,sass}',
path + 'components/sass/**/*.{scss,sass}'
],
outputStyle: 'nested',
lineNumbers: true,
},
files: [
{src: path + 'components/sass/style.scss', dest: path + 'style.css'}
],
}
},
// Uglify
uglify: {
my_target: {
options: {
sourceMap: true,
sourceMapName: path + 'scripts.min.map'
},
files: [
{src: path + 'components/js/*.js', dest: path + 'js/scripts.min.js'}
],
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', 'watch');
};
Same problem here. CPU stays at 50% on my i7 3770. Running on Windows 7.
We are probably watching between 500-1000 files.
I am also experiencing this issue on OSX 10.10.4 with grunt v0.4.5 and grunt-contrib-watch 0.6.1.
There are several other issues that seem to be related but apparently the underlying problem has not been fixed: https://github.com/gruntjs/grunt-contrib-watch/issues/35 https://github.com/gruntjs/grunt-contrib-watch/issues/145
I tried everything mentioned in those issues and nothing helped. Grunt is always using about 70% of my CPU and fseventsd is using about 15%.
Have to work on few projects (4-5) with grunts running in parallel, CPU usage in total is around 100% all the time .. single process is watching about 2000 files, and CPU goes up to 20-25 % And that is when I don't change files. If I comment out watch task, and leave only express running, CPU goes down to 2% Machine: SSD stripe 240GB, i7 quad cores, 16 GB RAM
I'm also seeing the same issue on OS X 10.10 with node 4.1.0 and grunt-contrib-watch 0.6.1.
Same issue here, but watching just 10 files. Grunt is using 100% of the CPU.
Have you tried this
options: { interval: 1000 },
That increases the latency and hurts the instantly responsive illusion.
I have the same issue with grunt 0.4.5 and grunt-watch 0.6.1 on OSX 10.10.5 Even with the interval option the CPU usage jumps to 100% as soon as I edit a file. And I have only about 10 files to watch!
@partnuz: this worked for me
Same problem with grunt 0.4.5 and grunt-watch 0.6.1 windows 7, watching 12 files, 100% CPU usage when editing files
options: { interval: 1000 },
hurts the instantly responsive illusion, but using a lower number, as 300
, reduced my CPU usage from 50% to 3-10%...
Good workaround until we figure something else.
Switching to https://github.com/JimRobs/grunt-chokidar (forked off of grunt-contrib-watch
but uses chokidar
instead of gaze
for file system watching) drops my CPU usage from ~25% to somewhere near 0% with the same functionality.
@shama @tkellen Would you consider a pull request to switch the underlying lib from gaze
to chokidar
?
@callmevlad see https://github.com/gruntjs/grunt-contrib-watch/issues/314
@vladikoff Thanks for the link! That issue is from a few years ago, and seems to make claims about Gaze >= 0.6 that don't seem to be true today at 1.0.0 (like not using native OS events instead of polling, for example), so I was hoping that decision would be revisited.
It would be great to get @shama's thoughts around which changes in https://github.com/JimRobs/grunt-chokidar/commit/a0f15e748bf8d5f5fcbf56022b0495e351819ff9 are incompatible two years later, or at least start a discussion around why gaze
must take up so much CPU as the number of watched files grows.
@callmevlad [email protected]
experimented with going fully to native events. It was certainly faster and consumed far less CPU but it caused a lot of issues. One issue is building the native addon can be challenging for users, especially on Windows. So 1.0.0
is basically an updated 0.5
, tabling going full native for now.
I'm not against revisiting chokidar
though. It's been awhile since I've evaluated implementing it here. AFAIK, chokidar requires the native addon fsevents
to be built on OSX (which isn't too bad) and just uses fs.watch
for other platforms. If chokidar is actually passing all the tests here as a drop in replacement for gaze, then they've certainly came a long way and I'd be really open to consider it.
Hey guys!
About this options: { interval: 1000 },
- where do I set this ?
I'm working with Magento 2.0 and I'm setting grunt.option('interval', 300);
in project's Gruntfile.js but my CPU is still 100% loaded...
Any idea why it doesn't work ?
Below you can see my Gruntfile.js
// For performance use one level down: 'name/{,*/}*.js'
// If you want to recursively match all subfolders, use: 'name/**/*.js'
module.exports = function (grunt) {
'use strict';
//grunt.option.init(); // best4u
grunt.option('interval', 300); // best4u
grunt.log.write(grunt.option.flags()); // best4u
var _ = require('underscore'),
path = require('path'),
themes = require('./dev/tools/grunt/configs/themes'),
configDir = './dev/tools/grunt/configs',
taskDir = './dev/tools/grunt/tasks';
[
taskDir + '/mage-minify',
taskDir + '/deploy',
taskDir + '/black-list-generator',
taskDir + '/clean-black-list',
taskDir + '/static',
'time-grunt'
].forEach(function (task) {
require(task)(grunt);
});
require('load-grunt-config')(grunt, {
configPath: path.join(__dirname, configDir),
init: true,
jitGrunt: {
staticMappings: {
usebanner: 'grunt-banner'
}
}
});
_.each({
/**
* Assembling tasks.
* ToDo: define default tasks.
*/
default: function () {
grunt.log.subhead('I\'m default task and at the moment I\'m empty, sorry :/');
},
/**
* Production preparation task.
*/
prod: function (component) {
var tasks = [
'less',
'autoprefixer',
'cssmin',
'usebanner'
].map(function(task){
return task + ':' + component;
});
if (typeof component === 'undefined') {
grunt.log.subhead('Tip: Please make sure that u specify prod subtask. By default prod task do nothing');
} else {
grunt.task.run(tasks);
}
},
/**
* Refresh themes.
*/
refresh: function () {
var tasks = [
'clean',
'exec:all'
];
_.each(themes, function(theme, name) {
tasks.push('less:' + name);
});
grunt.task.run(tasks);
},
/**
* Documentation
*/
documentation: [
'replace:documentation',
'less:documentation',
'styledocco:documentation',
'usebanner:documentationCss',
'usebanner:documentationLess',
'usebanner:documentationHtml',
'clean:var',
'clean:pub'
],
'legacy-build': [
'mage-minify:legacy'
],
spec: function (theme) {
var runner = require('./dev/tests/js/jasmine/spec_runner');
runner.init(grunt, { theme: theme });
grunt.task.run(runner.getTasks());
}
}, function (task, name) {
grunt.registerTask(name, task);
});
};
@vasilii-b grunt.option() is an interface for command line options. So grunt.option('stack', true)
in your Gruntfile is effectively the same as grunt --stack
.
interval
is a grunt-contrib-watch
task option that is defined in the options
of the task itself: http://gruntjs.com/configuring-tasks#options
Unfortunately your above Gruntfile is hiding the config so I'm not sure where that custom Gruntfile implementation expects watch task options. Typically with Gruntfiles, we recommend being explicit with the config:
grunt.initConfig({
watch: {
options: {
// Options for the watch task go here
interval: 5000
},
stuff: {
files: ['src/*.js'],
tasks: ['concat']
}
}
});
This has been bothering me for a while and I finally decided to look around today (my fan was constantly on). I tried the above mentioned chokidar
fork and my CPU usage is pretty much unnoticeable. My only concern is that that fork hasn't been actively maintained. It'd be great if that could be integrated into this extension.
I'm on Linux if that makes a difference. Based on this it seems like it works well on a Mac as well.
We ended up switching away from grunt-contrib-watch
-based file watching to use pm2
watchers (which use chokidar
under the hood) since we had to turn up the AC in the office to compensate for all the warm computers in the room caused by this issue 😬
Any activity planned on this one? Watch is still a problem. Grunt-chokidar solves it but is unmaintained and has few cosmetic issues.
I'm surprised this issue hasn't gotten more attention. Tons of web developers are at coffee shops with no power and here grunt-watch-contrib is eating up battery.
FWIW chokidar is pretty horrible on Windows and as proof VSCode stopped using it years ago on windows and wrote their own. The do use chokidar on Linux and Mac or did last time I checked. For Windows they wrote some small C# program and read its streamed output
https://github.com/microsoft/vscode/tree/master/src/vs/platform/files/node/watcher/win32
I'm still experiencing this on grunt-contrib-watch version 1.1.0
So it's almost 9 years now since the issue have been reported. Any progress on this? Is this repo still alive?
Okay, just use nodemon and let this repo die silently.