Bug 834999 - WebappsApplication.prototype.manifest getter takes 25-30ms on critical startup path r=ferjm
authorFabrice Desré <fabrice@mozilla.com>
Wed, 30 Jan 2013 14:22:54 -0800
changeset 120410 b8d1949eeb0528ebd2b7c651eae42480394285b7
parent 120409 3d90fdbf38a48b6b1a8a15dae7c678352fa9ecf0
child 120411 bd0fc79d7a8b311541be293e23f19ebc070ad719
push id24251
push userryanvm@gmail.com
push dateThu, 31 Jan 2013 20:56:22 +0000
treeherdermozilla-central@683b08dc1afd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersferjm
bugs834999
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 834999 - WebappsApplication.prototype.manifest getter takes 25-30ms on critical startup path r=ferjm
dom/apps/src/Webapps.js
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -328,16 +328,36 @@ DOMError.prototype = {
                                     flags: Ci.nsIClassInfo.DOM_OBJECT,
                                     classDescription: "DOMError object"})
 }
 
 /**
   * mozIDOMApplication object
   */
 
+// A simple cache for the wrapped manifests.
+let manifestCache = {
+  _cache: { },
+
+  // Gets an entry from the cache, and populates the cache if needed.
+  get : function mcache_get(aManifestURL, aManifest, aWindow) {
+    if (!(aManifestURL in this._cache)) {
+      this._cache[aManifestURL] = ObjectWrapper.wrap(aManifest, aWindow);
+    }
+    return this._cache[aManifestURL];
+  },
+
+  // Invalidates an entry in the cache.
+  evict: function mcache_evict(aManifestURL) {
+    if (aManifestURL in this._cache) {
+      delete this._cache[aManifestURL];
+    }
+  }
+}
+
 function createApplicationObject(aWindow, aApp) {
   let app = Cc["@mozilla.org/webapps/application;1"].createInstance(Ci.mozIDOMApplication);
   app.wrappedJSObject.init(aWindow, aApp);
   return app;
 }
 
 function WebappsApplication() {
   this.wrappedJSObject = this;
@@ -382,17 +402,17 @@ WebappsApplication.prototype = {
 
     cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
                           ["Webapps:OfflineCache",
                            "Webapps:PackageEvent",
                            "Webapps:CheckForUpdate:Return:OK"]);
   },
 
   get manifest() {
-    return this.manifest = ObjectWrapper.wrap(this._manifest, this._window);
+    return manifestCache.get(this.manifestURL, this._manifest, this._window);
   },
 
   get updateManifest() {
     return this.updateManifest = this._updateManifest ? ObjectWrapper.wrap(this._updateManifest, this._window)
                                                       : null;
   },
 
   set onprogress(aCallback) {
@@ -567,29 +587,32 @@ WebappsApplication.prototype = {
           case "canceled":
             this._downloadError = msg.error;
             this._fireEvent("downloaderror", this._ondownloaderror);
             break;
           case "progress":
             this._fireEvent("downloadprogress", this._onprogress);
             break;
           case "installed":
+            manifestCache.evict(this.manifestURL);
             this._manifest = msg.manifest;
             this._fireEvent("downloadsuccess", this._ondownloadsuccess);
             this._fireEvent("downloadapplied", this._ondownloadapplied);
             break;
           case "downloaded":
             // We don't update the packaged apps manifests until they
             // are installed or until the update is unstaged.
             if (msg.manifest) {
+              manifestCache.evict(this.manifestURL);
               this._manifest = msg.manifest;
             }
             this._fireEvent("downloadsuccess", this._ondownloadsuccess);
             break;
           case "applied":
+            manifestCache.evict(this.manifestURL);
             this._manifest = msg.manifest;
             this._fireEvent("downloadapplied", this._ondownloadapplied);
             break;
         }
         break;
     }
   },