Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High CPU usage #429

Open
asolopovas opened this issue Apr 16, 2015 · 24 comments
Open

High CPU usage #429

asolopovas opened this issue Apr 16, 2015 · 24 comments

Comments

@asolopovas
Copy link

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');
};
@acollard
Copy link

acollard commented Jun 8, 2015

Same problem here. CPU stays at 50% on my i7 3770. Running on Windows 7.

We are probably watching between 500-1000 files.

@Stratus3D
Copy link

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:
#35
#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%.

@kiril-chilingarashvili
Copy link

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

@yang
Copy link

yang commented Sep 25, 2015

I'm also seeing the same issue on OS X 10.10 with node 4.1.0 and grunt-contrib-watch 0.6.1.

@rogeraleite
Copy link

Same issue here, but watching just 10 files. Grunt is using 100% of the CPU.

@partnuz
Copy link

partnuz commented Nov 13, 2015

Have you tried this

options: { interval: 1000 },

@yang
Copy link

yang commented Nov 22, 2015

That increases the latency and hurts the instantly responsive illusion.

@netzbandit
Copy link

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!

@msierks
Copy link

msierks commented Jan 25, 2016

@partnuz: this worked for me

@eddyerburgh
Copy link

Same problem with grunt 0.4.5 and grunt-watch 0.6.1 windows 7, watching 12 files, 100% CPU usage when editing files

@HugoHeneault
Copy link

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.

@callmevlad
Copy link

callmevlad commented May 1, 2016

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?

@vladikoff
Copy link
Member

@callmevlad see #314

@callmevlad
Copy link

@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 jimmy-robert@a0f15e7 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.

@shama
Copy link
Member

shama commented May 1, 2016

@callmevlad gaze@0.6 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.

@vasilii-b
Copy link

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);
    });
};

@shama
Copy link
Member

shama commented May 30, 2016

@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']
    }
  }
});

@aiguofer
Copy link

aiguofer commented Oct 5, 2016

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.

@callmevlad
Copy link

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 😬

@rnemec
Copy link

rnemec commented Mar 17, 2017

Any activity planned on this one? Watch is still a problem. Grunt-chokidar solves it but is unmaintained and has few cosmetic issues.

@greggman
Copy link

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

@CVertex
Copy link

CVertex commented May 11, 2020

I'm still experiencing this on grunt-contrib-watch version 1.1.0

@meszaros-lajos-gyorgy
Copy link

So it's almost 9 years now since the issue have been reported. Any progress on this? Is this repo still alive?

@meszaros-lajos-gyorgy
Copy link

Okay, just use nodemon and let this repo die silently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests