wallabyjs / atom-wallaby

Wallaby.js atom package starter
Other
57 stars 6 forks source link

Slowness of Atom when running wallaby #68

Open gregorym opened 6 years ago

gregorym commented 6 years ago

Hi,

First of all, Wallaby is amazing, my team and I have been using it for a long time now.

Our application now has > 7000 unit tests, it takes a while for wallaby to run the initial 7000 tests but that's expected. However once Wallaby is running there is a noticeable slowness of Atom where everything has a ~200ms delay. Additionally, after modifying a test, Wallaby takes ~3-4 seconds to re-evaluate the tests and update it's UI.

What would I/you need to diagnose the issue? Thanks

ArtemGovorov commented 6 years ago

Could you please share your wallaby config file?

gregorym commented 6 years ago

wallaby.conf.js

'use strict';
var babel = require('babel-core');
var path = require('path');
var wallabyWebpack = require('wallaby-webpack');
var webpack = require('webpack');

var nodeModuleRegExp = /[\w-\/\\\.~:]*((\/|\\)lib(\/|\\)commonjs(\/|\\)|(\/|\\)node_modules(\/|\\)|(\/|\\)bower_components(\/|\\))[\w-\/\\.~]*\.js$/;

var xxxPath = 'tst/utilities/xxx';
var mousetrapPath = 'tst/utilities/mousetrap';
var testUtils = 'tst/utilities/testUtils';
var auiPath = 'tst/utilities/aui';
var maestroPath = 'tst/utilities/maestro';

module.exports = function(wallaby) {
    process.env.BABEL_ENV = 'test';

    let babelCompiler = wallaby.compilers.babel({
        babel: babel,
        presets: ['es2015', 'stage-1'],
        plugins: ['rewire-es5'],
    });
    let webpackPostProcessor = wallabyWebpack({
        module: {
            rules: [{ test: /\.html$/, loader: 'ractive-loader' }],
        },
        resolve: {
            modules: [path.join(wallaby.localProjectDir, 'node_modules'), wallaby.projectCacheDir],
            extensions: ['.html', '.js'],
            //For rx.js requires, let's ignore the 'browser' section
            //of package.json where it defines the file to load when you call
            //require('rx'). We will use our alias below instead.
            alias: {
                // substitute require('rx/index') for require('rx')
                // otherwise require('rx') requires rx.all which doesn't include the
                // test module that we use in our unit tests
                rx$: path.join(wallaby.projectCacheDir, 'src/rx'),
            },
        },
        //devtools: "source-map",
        plugins: [
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify('testing'),
                },
            }),
            new webpack.ProvidePlugin({
                xxx: xxxPath,
            }),
            new webpack.ProvidePlugin({
                Mousetrap: mousetrapPath,
            }),
            new webpack.ProvidePlugin({
                P: auiPath,
            }),
            new webpack.ProvidePlugin({
                testUtils: testUtils,
            }),
            new webpack.ProvidePlugin({
                Maestro: maestroPath,
            }),
        ],
    });

    return {
        files: [
            { pattern: 'node_modules/babel-polyfill/browser.js', instrument: false, load: true },
            { pattern: 'src/**/*.js', load: false },
            { pattern: 'src/**/*.html', load: false },
            { pattern: 'tst/helpers.js', load: false },
            { pattern: 'tst/utilities/*.js', load: false },
        ],

        tests: [{ pattern: 'tst/**/*spec.js', load: false }],

        compilers: {
            '**/*.js': babelCompiler,
        },

        postprocessor: webpackPostProcessor,

        testFramework: 'jasmine',

        bootstrap: function() {
            // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
            // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

            // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel

            // MIT license

            (function() {
                var lastTime = 0;
                var vendors = ['ms', 'moz', 'webkit', 'o'];
                for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
                    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
                    window.cancelAnimationFrame =
                        window[vendors[x] + 'CancelAnimationFrame'] ||
                        window[vendors[x] + 'CancelRequestAnimationFrame'];
                }

                if (!window.requestAnimationFrame)
                    window.requestAnimationFrame = function(callback, element) {
                        var currTime = new Date().getTime();
                        var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                        var id = window.setTimeout(function() {
                            callback(currTime + timeToCall);
                        }, timeToCall);
                        lastTime = currTime + timeToCall;
                        return id;
                    };

                if (!window.cancelAnimationFrame)
                    window.cancelAnimationFrame = function(id) {
                        clearTimeout(id);
                    };
            })();

            if (!Object.assign) {
                Object.defineProperty(Object, 'assign', {
                    enumerable: false,
                    configurable: true,
                    writable: true,
                    value: function(target) {
                        'use strict';
                        if (target === undefined || target === null) {
                            throw new TypeError('Cannot convert first argument to object');
                        }

                        var to = Object(target);
                        for (var i = 1; i < arguments.length; i++) {
                            var nextSource = arguments[i];
                            if (nextSource === undefined || nextSource === null) {
                                continue;
                            }
                            nextSource = Object(nextSource);

                            var keysArray = Object.keys(Object(nextSource));
                            for (
                                var nextIndex = 0, len = keysArray.length;
                                nextIndex < len;
                                nextIndex++
                            ) {
                                var nextKey = keysArray[nextIndex];
                                var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
                                if (desc !== undefined && desc.enumerable) {
                                    to[nextKey] = nextSource[nextKey];
                                }
                            }
                        }
                        return to;
                    },
                });
            }
            window.__moduleBundler.loadTests();
        },
    };
};
ArtemGovorov commented 6 years ago

Thanks.

However once Wallaby is running there is a noticeable slowness of Atom where everything has a ~200ms delay.

Is it during the initial Wallaby run, or incremental Wallaby runs are also causing the lags in the editor?

Additionally, after modifying a test, Wallaby takes ~3-4 seconds to re-evaluate the tests and update it's UI.

it may be that the time is spent in Webpack incrementally building the app after the change, but let's find out what exactly takes the time. Could you please