diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js index 3173d80c797..2c10e6ffca8 100644 --- a/app/assets/javascripts/discourse.js +++ b/app/assets/javascripts/discourse.js @@ -220,7 +220,6 @@ Discourse = Ember.Application.createWithMixins(Discourse.Ajax, { Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus); // Developer specific functions - Discourse.Development.setupProbes(); Discourse.Development.observeLiveChanges(); Discourse.subscribeUserToNotifications(); } diff --git a/app/assets/javascripts/discourse/components/development.js b/app/assets/javascripts/discourse/components/development.js index 675010e7b9d..4040a9da61b 100644 --- a/app/assets/javascripts/discourse/components/development.js +++ b/app/assets/javascripts/discourse/components/development.js @@ -7,77 +7,6 @@ **/ Discourse.Development = { - - /** - Set up probes for performance measurements. - - @method setupProbes - **/ - setupProbes: function() { - - // Don't probe if we don't have a console - if (typeof console === "undefined" || console === null) return; - - var topLevel = function(fn, name) { - return window.probes.measure(fn, { - name: name, - - before: function(data, owner, args) { - if (owner) { - return window.probes.clear(); - } - }, - - after: function(data, owner, args) { - - if (typeof console === "undefined") return; - if (console === null) return; - - var f, n, v; - if (owner && data.time > 10) { - - f = function(name, data) { - if (data && data.count) return name + " - " + data.count + " calls " + ((data.time + 0.0).toFixed(2)) + "ms"; - }; - - if (console.group) { - console.group(f(name, data)); - } else { - console.log(""); - console.log(f(name, data)); - } - - var ary = []; - for (n in window.probes) { - v = window.probes[n]; - if (n === name || v.time < 1) continue; - ary.push({ k: n, v: v }); - } - ary.sort(function(x,y) { - x = x.v && x.v.time ? -x.v.time : 0; - y = y.v && y.v.time ? -y.v.time : 0; - return x > y; - }); - _.each(ary, function(item,idx) { - var output = f("" + item.k, item.v); - if (output) { - console.log(output); - } - }); - - if (console.group) { - console.groupEnd(); - } - window.probes.clear(); - } - } - }); - }; - - Discourse.URL.routeTo = topLevel(Discourse.URL.routeTo, "Discourse.URL.routeTo"); - Ember.run.backburner.end = topLevel(Ember.run.backburner.end, "Ember.run.backburner.end"); - }, - /** Use the message bus for live reloading of components for faster development. diff --git a/app/assets/javascripts/external/ember-renderspeed.js b/app/assets/javascripts/external/ember-renderspeed.js new file mode 100644 index 00000000000..8df4fa4a9ce --- /dev/null +++ b/app/assets/javascripts/external/ember-renderspeed.js @@ -0,0 +1,103 @@ +// +// ember-renderspeed +// +// Include this script if you want to instrument your rendering speed in your Ember +// applications. +// +// https://github.com/eviltrout/ember-renderspeed +// +(function () { + + /** + Used for assembling a tree of render calls so they can be grouped and displayed + nicely afterwards. + + @class ProfileNode + **/ + var ProfileNode = Ember.Object.extend({ + + init: function() { + this.set('children', []); + }, + + /** + A string description of this node. If we have a template name we display that + too. + + @property description + **/ + description: function() { + var result = "Rendered "; + if (this.get('payload.template')) { + result += "'" + this.get('payload.template') + "' "; + } + + if (this.get('payload.object')) { + result += this.get('payload.object').toString() + " "; + } + result += (Math.round(this.get('time') * 100) / 100).toString() + "ms"; + return result; + }.property('time', 'payload.template', 'payload.object'), + + time: function() { + return this.get('end') - this.get('start'); + }.property('start', 'end'), + + /** + Adds a child node underneath this node. It also creates a reference between + the child and the parent. + + @method addChild + @param {ProfileNode} node the node we want as a child + **/ + addChild: function(node) { + node.set('parent', this); + this.get('children').pushObject(node); + }, + + /** + Logs this node and any children to the developer console, grouping appropriately + for easy drilling down. + + @method log + **/ + log: function() { + if ((!console) || (!console.groupCollapsed)) { return; } + + // We don't care about really fast renders + if (this.get('time') < 1) { return; } + + console.groupCollapsed(this.get('description')); + this.get('children').forEach(function (c) { + c.log(); + }); + console.groupEnd(); + } + }); + + + // Set up our instrumentation of Ember below + Ember.subscribe("render", { + depth: null, + + before: function(name, timestamp, payload) { + var node = ProfileNode.create({start: timestamp, payload: payload}); + + if (this.depth) { this.depth.addChild(node); } + this.depth = node; + + return node; + }, + + after: function(name, timestamp, payload, profileNode) { + this.depth = profileNode.get('parent'); + profileNode.set('end', timestamp); + + if (!this.depth) { + profileNode.log(); + } + } + }); + +})(); +