grunt-contrib-watch is a grunt plugin that runs one or more tasks whenever files in any of the watched file patterns are added, removed or changed.
In the early days of the project I have been working on, performances have been quite satisfactory and CPU wasn’t a problem. As in most of the projects, slowly the number of files increases and, with it, the CPU usage of grunt. The high load would immediately disappear as soon as you disabled the watch task.
Around the 1000 watched files mark, the CPU usage would sit constantly around 25%; enough to trigger the fan of my MacBook equipped with a 2.5GHz quad‑core Intel Core i7.
If you have run into the same issue, the first thing you could check is whether you are watching (hopefully by mistake) your node_modules folder; if that’s the case you can ignore it using the usual exclamation mark syntax:
watch: {
scripts: {
files: ["/**/*.js", '!node_modules/**/*.*'],
tasks: 'build'
}
}
Another easy fix is to increase the interval between checks, which, by default, is 100ms. As stated in their docs, the interval is only used by fs.watchfile and ingored by fs.watch, so it should be ignored; the improvements to the CPU usage are quite tangible though. Using a interval of 2 seconds brought down the percentage to about 3.
watch: {
scripts: {
files: ['**/*.js', '!node_modules/**/*.*'],
tasks: 'build'
},
options: {
interval: 2000
}
},
An alternative solution is to switch to a different plugin like grunt-chokidar, which is a fork of grunt-contrib-watch that uses chokidar. Chokidar is a wrapper around the nodejs fs library, that attempts to fix a few of the shortcomings of watch and watchfile. I can say that, at least on a Mac, it succeeds; it uses, in fact, the Darwin FSEvent API, which makes recursive watching very efficient compared to kqueue.
Being a fork of grunt-contrib-watch, to give it a try you just need to run:
npm install grunt-chokidar --save-dev
load the task and register an alias:
grunt.loadNpmTasks('grunt-chokidar');
grunt.registerTask('watch', ['chokidar']);
Now you can just rename the json configuration node from watch to chokidar and try it. In my tests grunt basically disappeared from the activity monitor, but I would like to know if anything changes on other platforms.