Bug 1443765: delay SessionStore for Fennec on input events r=snorp
authorRandell Jesup <rjesup@jesup.org>
Thu, 08 Mar 2018 17:12:49 -0500
changeset 407304 f34ad0155500e32c013d15b706986bc4726fd41c
parent 407303 f1431c234b4eb10d3c16067465bfc22e8699c1ed
child 407305 c1152eaf2036a18226b7e04f8359eff9aeb83cd8
push id33599
push userapavel@mozilla.com
push dateFri, 09 Mar 2018 19:34:23 +0000
treeherdermozilla-central@3dc420775cf0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1443765
milestone60.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 1443765: delay SessionStore for Fennec on input events r=snorp This also implies that a series of events (like UnselectAll for checkboxes) will be batched.
mobile/android/components/SessionStore.js
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -66,16 +66,17 @@ SessionStore.prototype = {
   _lastQueuedSaveTime: 0,
   _lastBackupTime: 0,
   _interval: 10000,
   _backupInterval: 120000, // 2 minutes
   _maxTabsUndo: 5,
   _pendingWrite: 0,
   _pendingWritePrivateOnly: 0,
   _scrollSavePending: null,
+  _formdataSavePending: null,
   _writeInProgress: false,
 
   // We only want to start doing backups if we've successfully
   // written the session data at least once.
   _sessionDataIsGood: false,
 
   // The index where the most recently closed tab was in the tabs array
   // when it was closed.
@@ -515,18 +516,30 @@ SessionStore.prototype = {
           // We're not restoring, capture the initial scroll position on pageshow.
           this.onTabScroll(window, browser);
         }
         break;
       }
       case "input":
       case "DOMAutoComplete": {
         let browser = aEvent.currentTarget;
-        log("TabInput for tab " + window.BrowserApp.getTabForBrowser(browser).id);
-        this.onTabInput(window, browser);
+        // Duplicated logging check to avoid calling getTabForBrowser on each input event.
+        if (loggingEnabled) {
+          log("TabInput for tab " + window.BrowserApp.getTabForBrowser(browser).id);
+        }
+        // Schedule saving instead of doing it immediately - immediate save will block activity, and in
+        // cases like checking or unchecking 100 checkboxes, this can cause long delays. (bug 1443765)
+        // XXX This may be better handled with idle detection similar to desktop (bug 1444222)
+        if (!this._formdataSavePending) {
+          this._formdataSavePending =
+            window.setTimeout(() => {
+              this._formdataSavePending = null;
+              this.onTabInput(window, browser);
+            }, 2000);
+        }
         break;
       }
       case "resize":
       case "scroll": {
         let browser = aEvent.currentTarget;
         // Duplicated logging check to avoid calling getTabForBrowser on each scroll event.
         if (loggingEnabled) {
           log(aEvent.type + " for tab " + window.BrowserApp.getTabForBrowser(browser).id);
@@ -838,16 +851,23 @@ SessionStore.prototype = {
 
     // The long press that initiated the move canceled any close undo option that may have been
     // present.
     this._lastClosedTabIndex = INVALID_TAB_INDEX;
     this.saveStateDelayed();
   },
 
   onTabInput: function ss_onTabInput(aWindow, aBrowser) {
+    // If we've been called directly, cancel any pending timeouts.
+    if (this._formdataSavePending) {
+      aWindow.clearTimeout(this._formdataSavePending);
+      this._formdataSavePending = null;
+      log("onTabInput() clearing pending timeout");
+    }
+
     // If this browser belongs to a zombie tab or the initial restore hasn't yet finished,
     // skip any session save activity.
     if (aBrowser.__SS_restore || !this._startupRestoreFinished || aBrowser.__SS_restoreReloadPending) {
       return;
     }
 
     // Don't bother trying to save text data if we don't have history yet
     let data = aBrowser.__SS_data;