sahat/hackathon-starter

Slow to start

vjpr opened this issue · 10 comments

vjpr commented

Takes about ~12 seconds to start (in Germany).

Connect assets is 6s, and then all the requires in api.js take a significant amount of time to start.

Possibly some apis are trying to make requests to the USA on startup.

What is the average startup time to expect?


Adding the following at the top of app.js and api.js...

var debug = require('debug')('test');
var req = require;
require = function(file) {
  debug("");
  var val = req(file);
  debug(file);
  return val;
};

...reveals the time required to parse/execute each required file:

  test connect-assets +369ms
  test  +0ms
  test ./controllers/home +1ms
  test  +0ms
  test ./controllers/user +219ms
  test  +0ms
  test  +6ms
  test ../config/secrets +1ms
  test  +0ms
  test ../models/User +0ms
  test  +0ms
  test querystring +0ms
  test  +1ms
  test validator +8ms
  test  +0ms
  test async +0ms
  test  +0ms
  test cheerio +270ms
  test  +1ms
  test request +263ms
  test  +0ms
  test fbgraph +304ms
  test  +1ms
  test lastfm +27ms
  test  +0ms
  test tumblr.js +71ms
  test  +0ms
  test node-foursquare +97ms
  test  +30ms
  test github-api +38ms
  test  +0ms
  test twit +21ms
  test  +0ms
  test ordrin-api +233ms
  test  +0ms
  test stripe +145ms
  test  +4ms
  test twilio +237ms
  test  +25ms
  test node-linkedin +32ms
  test  +316ms
  test clockwork +291ms
  test  +2ms
  test paypal-rest-sdk +65ms
  test  +1ms
  test lob +62ms
  test  +2ms
  test instagram-node +82ms
  test  +6ms
  test yui/yql +343ms
  test  +0ms
  test lodash +0ms
  test ./controllers/api +0ms
  test  +0ms
  test ./controllers/contact +3ms
  test  +0ms
  test ./config/secrets +0ms
  test  +0ms
  test ./config/passport +519ms
  express:application compile etag weak +0ms
  express:application compile query parser extended +2ms
  express:application compile trust proxy false +0ms
  express:application booting in development mode +1ms
  test  +24ms
  test connectAssets +6s
  test  +78ms
  test new MongoStore +16ms
  express:application  +6s
  express:application http.createServer +0ms
  express:application  +0ms
Express server listening on port 3000 in development mode
  test Total startup time +14ms 11953 ms

This is way to slow to iterate during a hackathon.

I think a remedy might be to require apis on demand instead of on startup.

sahat commented

You are correct about the slow startup times. I feel it is slow as well, but there is nothing much that I can do about it. It takes about 2-3 seconds to start on my computer, but even then I consider it super slow. Anything over half a second will feel slow.

I may be able to remove connect-assets dependency since it has the most impact and not worry about automatic minification and concatenation. For production mode it is nice, for hackathons - I don't think it is crucial to have the most optimized version of your app.

Now, as far as loading modules on demand, I am against that idea because it will litter the code with a bunch of flags and switch/if statements. What you can do is remove API modules that you don't need yourself. When you are not sure which package belongs to which API there is a list here:
https://github.com/sahat/hackathon-starter#list-of-packages

vjpr commented

We could simply access modules using require('module') when they are used. Node caches modules after first use. This would speed things up a lot.

Something like connect-assets is necessary for a hackathon starter, but it seems it has been poorly implemented inefficiently.

it's better to move to Gulp system for minification of assets,
so that gulp can start the nodejs, watch for it, and connect browsersync

sahat commented

@vjpr Please clarify:

We could simply access modules using require('module') when they are used. Node caches modules after first use. This would speed things up a lot.

Are you suggesting to break apart API examples into individual modules?

sahat commented

@rstormsf This has been discussed many times. I love gulp and use it in all my projects. Browsersync is awesome and I just started using it on my latest side-project.

However, these are additional dependencies and an extra mental overhead for the users. I want the experience to be as simple as node app.js, instead of having to globally install gulp first, then running gulpfile.js and letting it do a bunch of tasks for me. And If I am not familiar with Node.js streams, gulp tasks would look completely alien to me. If you want to use gulp.js or Grunt there are many other project skeletons similar to Hackathon Starter out there.

@sahat - awesome! Can you refer some links? Would like to see them.
Esp with ES6, iojs, gulp, - all hot stuff

vjpr commented

@sahat Instead of requiring all the apis at the top of the file. Require
them when they are first used (i.e. when the controller actions are
called). They will be cached the first time.

On 21 March 2015 at 21:59, Roman Storm notifications@github.com wrote:

@sahat https://github.com/sahat - awesome! Can you refer some links?
Would like to see them.
Esp with ES6, iojs, gulp, - all hot stuff


Reply to this email directly or view it on GitHub
#247 (comment)
.

sahat commented

screenshot 2015-09-27 16 09 17

After swappng connect-assets for node-sass-middleware and splitting declaration and initialization of node.js modules in api.js per @vjpr suggestion, the start-up time is now around 660ms - 680ms on my machine, compared to 2700ms before these changes.

I found that by using Gulp and Browser Sync, I could use nodemon to handle full app restarts and browser sync to handle browser refreshes whenever editing js/css,views. Browser sync makes the changes visible in micro seconds, compared to the 6 seconds it takes for expressjs to startup.

It would be possible to add this into the project, but not make it required to

Example gulp task..

// 'less','css','scripts',
gulp.task('browser-sync', ['redis-start', 'nodemon'], function() {

browserSync.init(null, {
    proxy: "http://localhost:3000",
     browser: "google chrome",
    port: 7000,
    open: false,
    notify: false,
});

// auto refresh browser if this stuff changes
gulp.watch("public/css/*.less").on('change', browserSync.reload);;
gulp.watch("views/**/*").on('change', browserSync.reload);
gulp.watch("public/**/*.js").on('change', browserSync.reload);

});