Bug 1302996 - Stop loading various useless SDK modules on early devtools startup. r=jryans
MozReview-Commit-ID: 5Roi7rmmbes
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -7,16 +7,17 @@
const Services = require("Services");
const osString = Services.appinfo.OS;
// Panels
loader.lazyGetter(this, "OptionsPanel", () => require("devtools/client/framework/toolbox-options").OptionsPanel);
loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspector/panel").InspectorPanel);
loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/client/webconsole/panel").WebConsolePanel);
loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/client/debugger/panel").DebuggerPanel);
+loader.lazyGetter(this, "NewDebuggerPanel", () => require("devtools/client/debugger/new/panel").DebuggerPanel);
loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/client/styleeditor/styleeditor-panel").StyleEditorPanel);
loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/client/shadereditor/panel").ShaderEditorPanel);
loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/client/canvasdebugger/panel").CanvasDebuggerPanel);
loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/client/webaudioeditor/panel").WebAudioEditorPanel);
loader.lazyGetter(this, "MemoryPanel", () => require("devtools/client/memory/panel").MemoryPanel);
loader.lazyGetter(this, "PerformancePanel", () => require("devtools/client/performance/panel").PerformancePanel);
loader.lazyGetter(this, "NetMonitorPanel", () => require("devtools/client/netmonitor/panel").NetMonitorPanel);
loader.lazyGetter(this, "StoragePanel", () => require("devtools/client/storage/panel").StoragePanel);
@@ -150,18 +151,16 @@ Tools.jsdebugger = {
build: function (iframeWindow, toolbox) {
return new DebuggerPanel(iframeWindow, toolbox);
}
};
function switchDebugger() {
if (Services.prefs.getBoolPref("devtools.debugger.new-debugger-frontend")) {
- const NewDebuggerPanel = require("devtools/client/debugger/new/panel").DebuggerPanel;
-
Tools.jsdebugger.url = "chrome://devtools/content/debugger/new/index.html";
Tools.jsdebugger.build = function (iframeWindow, toolbox) {
return new NewDebuggerPanel(iframeWindow, toolbox);
};
} else {
Tools.jsdebugger.url = "chrome://devtools/content/debugger/debugger.xul";
Tools.jsdebugger.build = function (iframeWindow, toolbox) {
return new DebuggerPanel(iframeWindow, toolbox);
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -13,17 +13,16 @@
**/
const {Cc, Ci, Cu} = require("chrome");
const Services = require("Services");
const promise = require("promise");
const defer = require("devtools/shared/defer");
const Telemetry = require("devtools/client/shared/telemetry");
const { gDevTools } = require("./devtools");
-const { when: unload } = require("sdk/system/unload");
// Load target and toolbox lazily as they need gDevTools to be fully initialized
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browser-menus");
loader.lazyRequireGetter(this, "findCssSelector", "devtools/shared/inspector/css-logic", true);
@@ -137,16 +136,26 @@ var gDevToolsBrowser = exports.gDevTools
break;
case "nsPref:changed":
if (prefName.endsWith("enabled")) {
for (let win of this._trackedBrowserWindows) {
this.updateCommandAvailability(win);
}
}
break;
+ case "quit-application":
+ gDevToolsBrowser.destroy({ shuttingDown: true });
+ break;
+ case "sdk:loader:destroy":
+ // This event is fired when the devtools loader unloads, which happens
+ // only when the add-on workflow ask devtools to be reloaded.
+ if (subject.wrappedJSObject == require('@loader/unload')) {
+ gDevToolsBrowser.destroy({ shuttingDown: false });
+ }
+ break;
}
},
_prefObserverRegistered: false,
ensurePrefObserver: function () {
if (!this._prefObserverRegistered) {
this._prefObserverRegistered = true;
@@ -725,29 +734,38 @@ var gDevToolsBrowser = exports.gDevTools
let tabStats = gDevToolsBrowser._tabStats;
this._telemetry.log(TABS_OPEN_PEAK_HISTOGRAM, tabStats.peakOpen);
this._telemetry.log(TABS_OPEN_AVG_HISTOGRAM, mean(tabStats.histOpen));
this._telemetry.log(TABS_PINNED_PEAK_HISTOGRAM, tabStats.peakPinned);
this._telemetry.log(TABS_PINNED_AVG_HISTOGRAM, mean(tabStats.histPinned));
},
/**
- * All browser windows have been closed, tidy up remaining objects.
+ * Either the SDK Loader has been destroyed by the add-on contribution
+ * workflow, or firefox is shutting down.
+
+ * @param {boolean} shuttingDown
+ * True if firefox is currently shutting down. We may prevent doing
+ * some cleanups to speed it up. Otherwise everything need to be
+ * cleaned up in order to be able to load devtools again.
*/
- destroy: function () {
+ destroy: function ({ shuttingDown }) {
Services.prefs.removeObserver("devtools.", gDevToolsBrowser);
Services.obs.removeObserver(gDevToolsBrowser, "browser-delayed-startup-finished");
- Services.obs.removeObserver(gDevToolsBrowser.destroy, "quit-application");
+ Services.obs.removeObserver(gDevToolsBrowser, "quit-application");
+ Services.obs.removeObserver(gDevToolsBrowser, "sdk:loader:destroy");
gDevToolsBrowser._pingTelemetry();
gDevToolsBrowser._telemetry = null;
for (let win of gDevToolsBrowser._trackedBrowserWindows) {
gDevToolsBrowser._forgetBrowserWindow(win);
}
+
+ gDevTools.destroy({ shuttingDown });
},
};
// Handle all already registered tools,
gDevTools.getToolDefinitionArray()
.forEach(def => gDevToolsBrowser._addToolToWindows(def));
// and the new ones.
gDevTools.on("tool-registered", function (ev, toolId) {
@@ -761,25 +779,22 @@ gDevTools.on("tool-registered", function
gDevTools.on("tool-unregistered", function (ev, toolId) {
gDevToolsBrowser._removeToolFromWindows(toolId);
});
gDevTools.on("toolbox-ready", gDevToolsBrowser._updateMenuCheckbox);
gDevTools.on("toolbox-destroyed", gDevToolsBrowser._updateMenuCheckbox);
-Services.obs.addObserver(gDevToolsBrowser.destroy, "quit-application", false);
+Services.obs.addObserver(gDevToolsBrowser, "quit-application", false);
Services.obs.addObserver(gDevToolsBrowser, "browser-delayed-startup-finished", false);
+// Watch for module loader unload. Fires when the tools are reloaded.
+Services.obs.addObserver(gDevToolsBrowser, "sdk:loader:destroy", false);
// Fake end of browser window load event for all already opened windows
// that is already fully loaded.
let enumerator = Services.wm.getEnumerator(gDevTools.chromeWindowType);
while (enumerator.hasMoreElements()) {
let win = enumerator.getNext();
if (win.gBrowserInit && win.gBrowserInit.delayedStartupFinished) {
gDevToolsBrowser._registerBrowserWindow(win);
}
}
-
-// Watch for module loader unload. Fires when the tools are reloaded.
-unload(function () {
- gDevToolsBrowser.destroy();
-});
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -13,43 +13,37 @@ loader.lazyRequireGetter(this, "Toolbox"
loader.lazyRequireGetter(this, "ToolboxHostManager", "devtools/client/framework/toolbox-host-manager", true);
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
const {defaultTools: DefaultTools, defaultThemes: DefaultThemes} =
require("devtools/client/definitions");
const EventEmitter = require("devtools/shared/event-emitter");
const {JsonView} = require("devtools/client/jsonview/main");
const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox");
-const {when: unload} = require("sdk/system/unload");
const {Task} = require("devtools/shared/task");
const FORBIDDEN_IDS = new Set(["toolbox", ""]);
const MAX_ORDINAL = 99;
/**
* DevTools is a class that represents a set of developer tools, it holds a
* set of tools and keeps track of open toolboxes in the browser.
*/
this.DevTools = function DevTools() {
this._tools = new Map(); // Map<toolId, tool>
this._themes = new Map(); // Map<themeId, theme>
this._toolboxes = new Map(); // Map<target, toolbox>
- // destroy() is an observer's handler so we need to preserve context.
- this.destroy = this.destroy.bind(this);
-
// JSON Viewer for 'application/json' documents.
JsonView.initialize();
AboutDevTools.register();
EventEmitter.decorate(this);
- Services.obs.addObserver(this.destroy, "quit-application", false);
-
// This is important step in initialization codepath where we are going to
// start registering all default tools and themes: create menuitems, keys, emit
// related events.
this.registerDefaults();
};
DevTools.prototype = {
// The windowtype of the main window, used in various tools. This may be set
@@ -465,30 +459,33 @@ DevTools.prototype = {
let toolbox = this._toolboxes.get(target);
if (toolbox == null) {
return promise.resolve(false);
}
return toolbox.destroy().then(() => true);
},
/**
- * Called to tear down a tools provider.
+ * Either the SDK Loader has been destroyed by the add-on contribution
+ * workflow, or firefox is shutting down.
+
+ * @param {boolean} shuttingDown
+ * True if firefox is currently shutting down. We may prevent doing
+ * some cleanups to speed it up. Otherwise everything need to be
+ * cleaned up in order to be able to load devtools again.
*/
- _teardown: function DT_teardown() {
- for (let [target, toolbox] of this._toolboxes) {
- toolbox.destroy();
+ destroy: function ({ shuttingDown }) {
+ // Do not cleanup everything during firefox shutdown, but only when
+ // devtools are reloaded via the add-on contribution workflow.
+ if (!shuttingDown) {
+ for (let [target, toolbox] of this._toolboxes) {
+ toolbox.destroy();
+ }
+ AboutDevTools.unregister();
}
- AboutDevTools.unregister();
- },
-
- /**
- * All browser windows have been closed, tidy up remaining objects.
- */
- destroy: function () {
- Services.obs.removeObserver(this.destroy, "quit-application");
for (let [key, tool] of this.getToolDefinitionMap()) {
this.unregisterTool(key, true);
}
JsonView.destroy();
gDevTools.unregisterDefaults();
@@ -504,13 +501,8 @@ DevTools.prototype = {
*[Symbol.iterator ]() {
for (let toolbox of this._toolboxes) {
yield toolbox;
}
}
};
const gDevTools = exports.gDevTools = new DevTools();
-
-// Watch for module loader unload. Fires when the tools are reloaded.
-unload(function () {
- gDevTools._teardown();
-});