summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/performance/browser_startup_content.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/performance/browser_startup_content.js')
-rw-r--r--browser/base/content/test/performance/browser_startup_content.js196
1 files changed, 196 insertions, 0 deletions
diff --git a/browser/base/content/test/performance/browser_startup_content.js b/browser/base/content/test/performance/browser_startup_content.js
new file mode 100644
index 0000000000..330f9b7655
--- /dev/null
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -0,0 +1,196 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* This test records which services, frame scripts, process scripts, and
+ * JS modules are loaded when creating a new content process.
+ *
+ * If you made changes that cause this test to fail, it's likely because you
+ * are loading more JS code during content process startup. Please try to
+ * avoid this.
+ *
+ * If your code isn't strictly required to show a page, consider loading it
+ * lazily. If you can't, consider delaying its load until after we have started
+ * handling user events.
+ */
+
+"use strict";
+
+/* Set this to true only for debugging purpose; it makes the output noisy. */
+const kDumpAllStacks = false;
+
+const known_scripts = {
+ modules: new Set([
+ "chrome://mochikit/content/ShutdownLeaksCollector.sys.mjs",
+
+ // General utilities
+ "resource://gre/modules/AppConstants.sys.mjs",
+ "resource://gre/modules/Timer.sys.mjs",
+ "resource://gre/modules/XPCOMUtils.sys.mjs",
+
+ // Logging related
+ "resource://gre/modules/Log.sys.mjs",
+
+ // Browser front-end
+ "resource:///actors/AboutReaderChild.sys.mjs",
+ "resource:///actors/LinkHandlerChild.sys.mjs",
+ "resource:///actors/SearchSERPTelemetryChild.sys.mjs",
+ "resource://gre/actors/ContentMetaChild.sys.mjs",
+ "resource://gre/modules/Readerable.sys.mjs",
+
+ // Telemetry
+ "resource://gre/modules/TelemetryControllerBase.sys.mjs", // bug 1470339
+ "resource://gre/modules/TelemetryControllerContent.sys.mjs", // bug 1470339
+
+ // Extensions
+ "resource://gre/modules/ExtensionProcessScript.sys.mjs",
+ "resource://gre/modules/ExtensionUtils.sys.mjs",
+ ]),
+ frameScripts: new Set([
+ // Test related
+ "chrome://mochikit/content/shutdown-leaks-collector.js",
+ ]),
+ processScripts: new Set([
+ "chrome://global/content/process-content.js",
+ "resource://gre/modules/extensionProcessScriptLoader.js",
+ ]),
+};
+
+if (!Services.appinfo.sessionHistoryInParent) {
+ known_scripts.modules.add(
+ "resource:///modules/sessionstore/ContentSessionStore.sys.mjs"
+ );
+}
+
+if (AppConstants.NIGHTLY_BUILD) {
+ // Browser front-end.
+ known_scripts.modules.add("resource:///actors/InteractionsChild.sys.mjs");
+}
+
+// Items on this list *might* load when creating the process, as opposed to
+// items in the main list, which we expect will always load.
+const intermittently_loaded_scripts = {
+ modules: new Set([
+ "resource://gre/modules/nsAsyncShutdown.sys.mjs",
+ "resource://gre/modules/sessionstore/Utils.sys.mjs",
+
+ // Translations code which may be preffed on.
+ "resource://gre/actors/TranslationsChild.sys.mjs",
+ "resource://gre/modules/ConsoleAPIStorage.sys.mjs", // Logging related.
+
+ // Session store.
+ "resource://gre/modules/sessionstore/SessionHistory.sys.mjs",
+
+ // Webcompat about:config front-end. This is part of a system add-on which
+ // may not load early enough for the test.
+ "resource://webcompat/AboutCompat.jsm",
+
+ // Cookie banner handling.
+ "resource://gre/actors/CookieBannerChild.sys.mjs",
+ "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
+
+ // Test related
+ "chrome://remote/content/marionette/actors/MarionetteEventsChild.sys.mjs",
+ "chrome://remote/content/shared/Log.sys.mjs",
+ "resource://testing-common/BrowserTestUtilsChild.sys.mjs",
+ "resource://testing-common/ContentEventListenerChild.sys.mjs",
+ "resource://specialpowers/AppTestDelegateChild.sys.mjs",
+ "resource://testing-common/SpecialPowersChild.sys.mjs",
+ "resource://testing-common/WrapPrivileged.sys.mjs",
+ ]),
+ frameScripts: new Set([]),
+ processScripts: new Set([
+ // Webcompat about:config front-end. This is presently nightly-only and
+ // part of a system add-on which may not load early enough for the test.
+ "resource://webcompat/aboutPageProcessScript.js",
+ ]),
+};
+
+const forbiddenScripts = {
+ services: new Set([
+ "@mozilla.org/base/telemetry-startup;1",
+ "@mozilla.org/embedcomp/default-tooltiptextprovider;1",
+ "@mozilla.org/push/Service;1",
+ ]),
+};
+
+add_task(async function () {
+ SimpleTest.requestCompleteLog();
+
+ let tab = await BrowserTestUtils.openNewForegroundTab({
+ gBrowser,
+ url:
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "https://example.com"
+ ) + "file_empty.html",
+ forceNewProcess: true,
+ });
+
+ let mm = gBrowser.selectedBrowser.messageManager;
+ let promise = BrowserTestUtils.waitForMessage(mm, "Test:LoadedScripts");
+
+ // Load a custom frame script to avoid using ContentTask which loads Task.jsm
+ mm.loadFrameScript(
+ "data:text/javascript,(" +
+ function () {
+ /* eslint-env mozilla/frame-script */
+ const Cm = Components.manager;
+ Cm.QueryInterface(Ci.nsIServiceManager);
+ const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+ );
+ let collectStacks = AppConstants.NIGHTLY_BUILD || AppConstants.DEBUG;
+ let modules = {};
+ for (let module of Cu.loadedJSModules) {
+ modules[module] = collectStacks
+ ? Cu.getModuleImportStack(module)
+ : "";
+ }
+ for (let module of Cu.loadedESModules) {
+ modules[module] = collectStacks
+ ? Cu.getModuleImportStack(module)
+ : "";
+ }
+ let services = {};
+ for (let contractID of Object.keys(Cc)) {
+ try {
+ if (
+ Cm.isServiceInstantiatedByContractID(contractID, Ci.nsISupports)
+ ) {
+ services[contractID] = "";
+ }
+ } catch (e) {}
+ }
+ sendAsyncMessage("Test:LoadedScripts", {
+ modules,
+ services,
+ });
+ } +
+ ")()",
+ false
+ );
+
+ let loadedInfo = await promise;
+
+ // Gather loaded frame scripts.
+ loadedInfo.frameScripts = {};
+ for (let [uri] of Services.mm.getDelayedFrameScripts()) {
+ loadedInfo.frameScripts[uri] = "";
+ }
+
+ // Gather loaded process scripts.
+ loadedInfo.processScripts = {};
+ for (let [uri] of Services.ppmm.getDelayedProcessScripts()) {
+ loadedInfo.processScripts[uri] = "";
+ }
+
+ await checkLoadedScripts({
+ loadedInfo,
+ known: known_scripts,
+ intermittent: intermittently_loaded_scripts,
+ forbidden: forbiddenScripts,
+ dumpAllStacks: kDumpAllStacks,
+ });
+
+ BrowserTestUtils.removeTab(tab);
+});