From 30c66003e8490c63eff8c6f617ce5cd93814291a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 8 May 2013 14:47:13 +0200 Subject: [PATCH] profiling is back --- bin/config-optimist.js | 2 ++ bin/convert-argv.js | 2 ++ lib/Compilation.js | 24 ++++++++++++++ lib/Stats.js | 73 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/bin/config-optimist.js b/bin/config-optimist.js index 76c5c1533..fa6d304f2 100644 --- a/bin/config-optimist.js +++ b/bin/config-optimist.js @@ -61,6 +61,8 @@ module.exports = function(optimist) { .boolean("bail").describe("bail") + .boolean("profile").describe("profile") + .boolean("d").describe("d", "shortcut for --debug --devtool sourcemap --output-pathinfo") .boolean("p").describe("p", "shortcut for --optimize-minimize"); diff --git a/bin/convert-argv.js b/bin/convert-argv.js index 16723fe64..17c36c2f6 100644 --- a/bin/convert-argv.js +++ b/bin/convert-argv.js @@ -274,6 +274,8 @@ module.exports = function(optimist, argv, convertOptions) { mapArgToBoolean("bail", "bail"); + mapArgToBoolean("profile", "profile"); + if(!options.output || !options.output.filename) { ensureObject(options, "output"); if(convertOptions && convertOptions.outputFilename) { diff --git a/lib/Compilation.js b/lib/Compilation.js index 663ccb078..debb3d61e 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -27,6 +27,7 @@ function Compilation(compiler) { var options = this.options = compiler.options; this.outputOptions = options && options.output; this.bail = options && options.bail; + this.profile = options && options.profile; this.entries = []; this.chunks = []; this.namedChunks = {}; @@ -154,6 +155,7 @@ Compilation.prototype.processModuleDependencies = function(module, callback) { }.bind(this); var factory = item[0]; + if(this.profile) var start = +new Date(); factory.create(module.context, dependencies[0], function(err, dependantModule) { function isOptional() { return dependencies.filter(function(d) { return !d.optional }).length == 0; @@ -166,7 +168,13 @@ Compilation.prototype.processModuleDependencies = function(module, callback) { } if(err) return errorOrWarningAndCallback(new ModuleNotFoundError(module, err)); if(!dependantModule) return callback(); + if(this.profile) { + if(!dependantModule.profile) dependantModule.profile = {}; + var afterFactory = +new Date(); + dependantModule.profile.factory = afterFactory - start; + } + dependantModule.issuer = module.identifier(); var newModule = this.addModule(dependantModule); if(!newModule) { @@ -177,10 +185,21 @@ Compilation.prototype.processModuleDependencies = function(module, callback) { dependantModule.addReason(module, dep); }); + if(this.profile) { + if(!module.profile) module.profile = {}; + var time = +new Date() - start; + if(!module.profile.dependencies || time > module.profile.dependencies) + module.profile.dependencies = time; + } + return callback(); } if(newModule instanceof Module) { // from cache + if(this.profile) + newModule.profile = dependantModule.profile; + + newModule.issuer = dependantModule.issuer; dependantModule = newModule; dependencies.forEach(function(dep) { @@ -199,6 +218,11 @@ Compilation.prototype.processModuleDependencies = function(module, callback) { dependantModule.addReason(module, dep); }); + if(this.profile) { + var afterBuilding = +new Date(); + dependantModule.profile.building = afterBuilding - afterFactory; + } + this.processModuleDependencies(dependantModule, callback); }.bind(this)); diff --git a/lib/Stats.js b/lib/Stats.js index 91687072a..54fb0bcdb 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -116,7 +116,9 @@ Stats.prototype.toJson = function toJson(options, forToString) { built: !!module.built, chunks: module.chunks.map(function(chunk) { return chunk.id; - }) + }), + issuer: module.issuer, + profile: module.profile }; if(showReasons) { obj.reasons = module.reasons.filter(function(reason) { @@ -227,6 +229,22 @@ Stats.jsonToString = function jsonToString(obj, useColors) { buf.push(str); if(useColors) buf.push("\033[39m\033[22m"); } + function coloredTime(time) { + var times = [800, 400, 200, 100]; + if(obj.time) { + times = [obj.time/2, obj.time/4, obj.time/8, obj.time/16]; + } + if(time < times[3]) + normal(time + "ms"); + else if(time < times[2]) + bold(time + "ms"); + else if(time < times[1]) + green(time + "ms"); + else if(time < times[0]) + yellow(time + "ms"); + else + red(time + "ms"); + } function newline() { buf.push("\n"); } @@ -291,6 +309,57 @@ Stats.jsonToString = function jsonToString(obj, useColors) { }); table(t, [green, normal, bold, green, normal], "rrrll"); } + var modulesByIdentifier = {}; + if(obj.modules) { + obj.modules.forEach(function(module) { + modulesByIdentifier["$"+module.identifier] = module; + }); + } else { + obj.chunks.forEach(function(chunk) { + chunk.modules.forEach(function(module) { + modulesByIdentifier["$"+module.identifier] = module; + }); + }); + } + function processProfile(module) { + if(module.profile) { + normal(" "); + var sum = 0, allowSum = true; + var path = []; + var current = module; + while(current.issuer) { + if(!modulesByIdentifier["$"+current.issuer]) { + normal(" ... ->"); + allowSum = false; + break; + } + path.unshift(current = modulesByIdentifier["$"+current.issuer]); + } + path.forEach(function(module) { + normal(" ["); + normal(module.id); + normal("] "); + if(module.profile) { + var time = (module.profile.factory || 0) + (module.profile.building || 0); + coloredTime(time); + sum += time; + normal(" "); + } + normal("->"); + }); + Object.keys(module.profile).forEach(function(key) { + normal(" " + key + ":"); + var time = module.profile[key]; + coloredTime(time); + sum += time; + }); + if(allowSum) { + normal(" = "); + coloredTime(sum); + } + newline(); + } + } if(obj.chunks) { obj.chunks.forEach(function(chunk) { normal("chunk "); @@ -360,6 +429,7 @@ Stats.jsonToString = function jsonToString(obj, useColors) { newline(); }); } + processProfile(module); }); } }); @@ -406,6 +476,7 @@ Stats.jsonToString = function jsonToString(obj, useColors) { newline(); }); } + processProfile(module); }); } if(obj.warnings) {