Bug 1456291: Avoid loading the blocklist service before UI is interactive. r?Gijs
The TelemetryEnvironment initialization process currently forces a load and
initialization of the blocklist service only to check its isLoaded flag. This
adds measurable overhead to startup, and without those checks, the service
would not be initialized until after first paint.
We should defer even checking whether the blocklist is loaded until after
startup has finished.
MozReview-Commit-ID: 73c4o5oVqze
--- a/toolkit/components/telemetry/TelemetryEnvironment.jsm
+++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm
@@ -507,17 +507,17 @@ EnvironmentAddonBuilder.prototype = {
() => this._shutdownBlocker());
} catch (err) {
return Promise.reject(err);
}
this._pendingTask = (async () => {
try {
// Gather initial addons details
- await this._updateAddons();
+ await this._updateAddons(true);
if (!this._environment._addonsAreFull) {
// The addon database has not been loaded, so listen for the event
// triggered by the AddonManager when it is loaded so we can
// immediately gather full data at that time.
await new Promise(resolve => {
const ADDON_LOAD_NOTIFICATION = "xpi-database-loaded";
Services.obs.addObserver({
@@ -622,33 +622,37 @@ EnvironmentAddonBuilder.prototype = {
},
/**
* Collect the addon data for the environment.
*
* This should only be called from _pendingTask; otherwise we risk
* running this during addon manager shutdown.
*
+ * @param {boolean} [atStartup]
+ * True if this is the first check we're performing at startup. In that
+ * situation, we defer some more expensive initialization.
+ *
* @returns Promise<Object> This returns a Promise resolved with a status object with the following members:
* changed - Whether the environment changed.
* oldEnvironment - Only set if a change occured, contains the environment data before the change.
*/
- async _updateAddons() {
+ async _updateAddons(atStartup) {
this._environment._log.trace("_updateAddons");
let personaId = null;
let theme = LightweightThemeManager.currentTheme;
if (theme) {
personaId = theme.id;
}
let addons = {
activeAddons: await this._getActiveAddons(),
theme: await this._getActiveTheme(),
- activePlugins: this._getActivePlugins(),
- activeGMPlugins: await this._getActiveGMPlugins(),
+ activePlugins: this._getActivePlugins(atStartup),
+ activeGMPlugins: await this._getActiveGMPlugins(atStartup),
activeExperiment: {},
persona: personaId,
};
let result = {
changed: !this._environment._currentEnvironment.addons ||
!ObjectUtils.deepEqual(addons, this._environment._currentEnvironment.addons),
};
@@ -746,22 +750,27 @@ EnvironmentAddonBuilder.prototype = {
};
}
return activeTheme;
},
/**
* Get the plugins data in object form.
+ *
+ * @param {boolean} [atStartup]
+ * True if this is the first check we're performing at startup. In that
+ * situation, we defer some more expensive initialization.
+ *
* @return Object containing the plugins data.
*/
- _getActivePlugins() {
+ _getActivePlugins(atStartup) {
// If we haven't yet loaded the blocklist, pass back dummy data for now,
// and add an observer to update this data as soon as we get it.
- if (!Services.blocklist.isLoaded) {
+ if (atStartup || !Services.blocklist.isLoaded) {
if (!this._blocklistObserverAdded) {
Services.obs.addObserver(this, BLOCKLIST_LOADED_TOPIC);
this._blocklistObserverAdded = true;
}
return [{
name: "dummy", version: "0.1", description: "Blocklist unavailable",
blocklisted: false, disabled: true, clicktoplay: false,
mimeTypes: ["text/there.is.only.blocklist"],
@@ -798,25 +807,30 @@ EnvironmentAddonBuilder.prototype = {
}
}
return activePlugins;
},
/**
* Get the GMPlugins data in object form.
+ *
+ * @param {boolean} [atStartup]
+ * True if this is the first check we're performing at startup. In that
+ * situation, we defer some more expensive initialization.
+ *
* @return Object containing the GMPlugins data.
*
* This should only be called from _pendingTask; otherwise we risk
* running this during addon manager shutdown.
*/
- async _getActiveGMPlugins() {
+ async _getActiveGMPlugins(atStartup) {
// If we haven't yet loaded the blocklist, pass back dummy data for now,
// and add an observer to update this data as soon as we get it.
- if (!Services.blocklist.isLoaded) {
+ if (atStartup || !Services.blocklist.isLoaded) {
if (!this._blocklistObserverAdded) {
Services.obs.addObserver(this, BLOCKLIST_LOADED_TOPIC);
this._blocklistObserverAdded = true;
}
return {
"dummy-gmp": {version: "0.1", userDisabled: false, applyBackgroundUpdates: true}
};
}