carrot / roots-browserify

Roots v3 extension that uses browserify as a javascript pipeline
Other
21 stars 8 forks source link

Seemingly slow compilation #11

Closed sethkrasnianski closed 9 years ago

sethkrasnianski commented 9 years ago

I've just switched from js-pipline (great stuff) as a js build tool to this extension. I wanted more flexibility with modules that browserify offers. The only issue I've been having is ~25 second compilation times which are significantly slower than with js-pipeline's 1 - 3 second compilations. I understand there's a bit of work going on behind the scenes with compiling the coffeescript, transforming browserify to use bower modules and the actual compilation browserify does to concat the modules. But I question if this is expected with the two extra transformers? Any insight will be much appreciated :smile:

aside from requireing this module, this is my pertinent app.coffee:

    browserify(
      files: "assets/js/main.coffee"
      out: 'js/main.js'
      transforms: [
        'coffeeify'
        'debowerify'
      ]
    )
jescalan commented 9 years ago

Yeah so I definitely have had the same experience. I think the reason behind this is simply that browserify is slow and is doing a ton of things as you mentioned. The code itself is a rather straightforward wrapper over browserify. I have a couple thoughts on this:

First, when I use browserify, I don't always browserify everything. For example, I usually just load jquery as a script tag from google's CDN because it's exposed as a global and available wherever in your browserify scripts, and in all likelihood jquery has already been loaded and cached by some other website because of it's popularity. Same with any other common scripts like facebook, social buttons, etc. This does speed up the compile time a bit because jquery is massive.

Second, I think we could definitely work on cacheing a little bit to make it quicker. I know there are other browserify plugins that exist which cache (I think watchify does), and there's no reason we couldn't do it too. I just haven't got around to implementing this yet. If you are interested, I'd love to see you take a stab at it as well!

sethkrasnianski commented 9 years ago

I'll definitely try out the jQuery recommendation. When I get a bit of time I'll most definitely take a stab at it. I appreciate the insight.

zspecza commented 9 years ago

Watchify will definitely solve a lot of this due to the incremental build process. I've had some experience with it, so I'll see if I can get this in when I next have some free time.

Although, incremental builds won't offer 100% of the build optimisation here. If you want to take full advantage, it would be better to also structure your project in such a way that any vendor libraries are bundled externally, since those don't change much, and that way you'd just be compiling your application logic.

You could bundle this all together into one build for production only, but I think fetching from CDN and then only including the vendor bundle when the CDNs don't work would be better in any case.

In the case that I don't find the time to do this any time soon, I do have a Gulpfile where I've used Watchify that can be used as reference material: https://github.com/io-digital/io-angular/blob/master/templates/gulpfile.js#L234

zspecza commented 9 years ago

I've forked this project and added Watchify but I'm not seeing any benefit whatsoever to doing so, the compile process is still rather slow. This is unexpected behavior since I've always seen improvement when using Watchify (that Gulpfile example I posted in my previous comment was a 7s-300ms reduction in compile time after the initial compile after adding Watchify). This indicates that roots-browserify ends the process after a compile is finished. Is there any way to keep the process open?

// cc @samccone - maybe you can help me out here, since Jeff is Pirating the Globe?

jescalan commented 9 years ago

So if you want a process to stay open, you can initialize it inside the extension's function wrapper but outside the class. Any code in that portion of the extension will stay running during watch, and anything inside the class will be re-initialized each compile :grinning:

zspecza commented 9 years ago

@jenius - apologies for the late reply, I didn't see this until today. That's actually what I did (by coincidence alone), but it offered no improvement to compilation time... I think perhaps I do not understand the extension lifecycle completely enough to be of much more use in this regard... Think maybe in September you could explain it to me in person over a beer? :D

jescalan commented 9 years ago

Definitely, maybe we can try to pair it. Sorry I don't have more capacity to work this out at the moment!