Search code examples
node.jsasynchronousjakeuglifyjs

Is my conceptual misunderstanding of node async wrong?


I'm playing around with Node.js as a driver for some build time javascript optimization.

I've the following Jake file:

fs = require("fs")
uglify = require("uglify-js")
desc "Uglify JS"

bundles =
    edit: [ "jquery",.... ]
    login: [ ... ]
    directory: [ .... ]

all = {}
task "minify", [], (params) ->
  files = bundles.edit
  for name,files of bundles
    all[name] = ""
    files.forEach (file, i) ->
        file = file + ".js"
        all[name] += fs.readFileSync("Src/Scripts/" + file).toString()  if file.match(/^.*js$/)
        cbgen = (data) -> 
            (err, out) ->
                    ast = uglify.parser.parse(data)
                    ast = uglify.uglify.ast_mangle(ast)
                    ast = uglify.uglify.ast_squeeze(ast)
                    fs.write out, uglify.uglify.gen_code(ast), 0, null, null, (e,w) ->
        cb = cbgen all[name]
        fs.open "Src/Scripts/" + name + ".min.js", "w+", 0666, cb # async methods

and you can see on the last line, I’ve made the expensive part of the script asynchronous.

But when I run it, it only uses 12% of available CPU capacity so two questions:

  1. Am I doing it wrong
  2. If not, where's the upside?

Solution

  • I don't think your understanding is off, there's just not much of an upside in this example. Uglify/js minification is heavily CPU bound (parsing, ast manipulation, etc...) so I'd expect node to effectively run these operations serially.

    If not waiting Node will use 100% of the CPU that it has been allocated. If you're seeing it use around 12% then your machine likely has eight cores and Node is occupying one of them.

    There's probably little point for a build script but if really you wanted to run this optimally you could make sure all IO (reading files in this case) is being done asynchronously and spawn a separate process to do the uglification so that each bundle could be done in parallel.