Bug 1578375 - Stop flushing layout in SearchOneOffs::__rebuild when used with the address bar. r=adw a=lizzard
authorDão Gottwald <dao@mozilla.com>
Tue, 03 Sep 2019 18:32:32 +0000
changeset 554901 f4a413a2ebbbe0ed89f94575c27a230a7e126955
parent 554900 7c06991f7561f5be48f3f5342e7c881923aace8a
child 554902 df2eccb35ba5595e44939baa532c35dbf874d9e3
push id2165
push userffxbld-merge
push dateMon, 14 Oct 2019 16:30:58 +0000
treeherdermozilla-release@0eae18af659f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw, lizzard
bugs1578375
milestone70.0
Bug 1578375 - Stop flushing layout in SearchOneOffs::__rebuild when used with the address bar. r=adw a=lizzard Differential Revision: https://phabricator.services.mozilla.com/D44449
browser/base/content/test/performance/browser_urlbar_keyed_search.js
browser/base/content/test/performance/browser_urlbar_search.js
browser/components/search/content/search-one-offs.js
--- a/browser/base/content/test/performance/browser_urlbar_keyed_search.js
+++ b/browser/base/content/test/performance/browser_urlbar_keyed_search.js
@@ -8,32 +8,20 @@
  * the front-end. Instead of adding more reflows to the whitelist, you should
  * be modifying your code to avoid the reflow.
  *
  * See https://developer.mozilla.org/en-US/Firefox/Performance_best_practices_for_Firefox_fe_engineers
  * for tips on how to do that.
  */
 
 /* These reflows happen only the first time the panel opens. */
-const EXPECTED_REFLOWS_FIRST_OPEN = [
-  {
-    stack: [
-      "__rebuild@chrome://browser/content/search/search-one-offs.js",
-      /* This is limited to a one-line stack, because the next item is an async
-         function and as such not supported on all trees, according to bug 1501761.
-      "async*_rebuild@chrome://browser/content/search/search-one-offs.js",
-      "async*_on_popupshowing@chrome://browser/content/search/search-one-offs.js",
-      "handleEvent@chrome://browser/content/search/search-one-offs.js",
-      "_openPanel@resource:///modules/UrlbarView.jsm",
-      "onQueryResults@resource:///modules/UrlbarView.jsm",
-      "_notify@resource:///modules/UrlbarController.jsm",
-      "receiveResults@resource:///modules/UrlbarController.jsm",
-      "notifyResults@resource:///modules/UrlbarProvidersManager.jsm",
-      "add@resource:///modules/UrlbarProvidersManager.jsm",
-      "onSearchResult@resource:///modules/UrlbarProviderUnifiedComplete.jsm",
-      */
-    ],
-  },
-];
+const EXPECTED_REFLOWS_FIRST_OPEN = [];
+
+/* These reflows happen every time the panel opens. */
+const EXPECTED_REFLOWS_SECOND_OPEN = [];
 
 add_task(async function quantumbar() {
-  await runUrlbarTest(true, EXPECTED_REFLOWS_FIRST_OPEN);
+  await runUrlbarTest(
+    true,
+    EXPECTED_REFLOWS_FIRST_OPEN,
+    EXPECTED_REFLOWS_SECOND_OPEN
+  );
 });
--- a/browser/base/content/test/performance/browser_urlbar_search.js
+++ b/browser/base/content/test/performance/browser_urlbar_search.js
@@ -8,36 +8,17 @@
  * the front-end. Instead of adding more reflows to the whitelist, you should
  * be modifying your code to avoid the reflow.
  *
  * See https://developer.mozilla.org/en-US/Firefox/Performance_best_practices_for_Firefox_fe_engineers
  * for tips on how to do that.
  */
 
 /* These reflows happen only the first time the panel opens. */
-const EXPECTED_REFLOWS_FIRST_OPEN = [
-  {
-    stack: [
-      "__rebuild@chrome://browser/content/search/search-one-offs.js",
-      /* This is limited to a one-line stack, because the next item is an async
-         function and as such not supported on all trees, according to bug 1501761.
-      "async*_rebuild@chrome://browser/content/search/search-one-offs.js",
-      "async*_on_popupshowing@chrome://browser/content/search/search-one-offs.js",
-      "handleEvent@chrome://browser/content/search/search-one-offs.js",
-      "_openPanel@resource:///modules/UrlbarView.jsm",
-      "onQueryResults@resource:///modules/UrlbarView.jsm",
-      "_notify@resource:///modules/UrlbarController.jsm",
-      "receiveResults@resource:///modules/UrlbarController.jsm",
-      "notifyResults@resource:///modules/UrlbarProvidersManager.jsm",
-      "add@resource:///modules/UrlbarProvidersManager.jsm",
-      "onSearchResult@resource:///modules/UrlbarProviderUnifiedComplete.jsm",
-      */
-    ],
-  },
-];
+const EXPECTED_REFLOWS_FIRST_OPEN = [];
 
 /* These reflows happen every time the panel opens. */
 const EXPECTED_REFLOWS_SECOND_OPEN = [];
 
 add_task(async function quantumbar() {
   await runUrlbarTest(
     false,
     EXPECTED_REFLOWS_FIRST_OPEN,
--- a/browser/components/search/content/search-one-offs.js
+++ b/browser/components/search/content/search-one-offs.js
@@ -167,17 +167,17 @@ class SearchOneOffs {
       throw new Error("Unrecognized search-one-offs event: " + event.type);
     }
   }
 
   /**
    * Width in pixels of the one-off buttons.
    */
   get buttonWidth() {
-    return this.compact ? 40 : 48;
+    return 48;
   }
 
   /**
    * Height in pixels of the one-off buttons.
    */
   get buttonHeight() {
     return 32;
   }
@@ -471,61 +471,55 @@ class SearchOneOffs {
       // Hide everything except the settings button.
       this.header.hidden = this.buttons.hidden = hideOneOffs;
     }
 
     if (hideOneOffs) {
       return;
     }
 
-    // this.buttonWidth is for the compact settings button.
-    let buttonsWidth = this.compact
-      ? this._textboxWidth - this.buttonWidth - this.header.clientWidth
-      : this.popup.clientWidth;
-
-    // There's one weird thing to guard against: when layout pixels
-    // aren't an integral multiple of device pixels, the last button
-    // of each row sometimes gets pushed to the next row, depending on the
-    // panel and button widths.
-    // This is likely because the clientWidth getter rounds the value, but
-    // the panel's border width is not an integer.
-    // As a workaround, decrement the width if the scale is not an integer.
-    let scale = window.windowUtils.screenPixelsPerCSSPixel;
-    if (Math.floor(scale) != scale) {
-      --buttonsWidth;
-    }
-
-    // If the header string is very long, then the searchbar buttons will
-    // overflow their container unless max-width is set.
     if (this.compact) {
       this.spacerCompact.setAttribute("flex", "1");
-    } else {
-      this.buttons.style.setProperty("max-width", `${buttonsWidth}px`);
-    }
-
-    // 24: 12px left padding + 12px right padding.
-    if (this.compact) {
-      buttonsWidth -= 24;
     }
 
-    // In very narrow windows, we should always have at least one button
-    // per row.
-    buttonsWidth = Math.max(buttonsWidth, this.buttonWidth);
+    if (this.popup) {
+      let buttonsWidth = this.popup.clientWidth;
+
+      // There's one weird thing to guard against: when layout pixels
+      // aren't an integral multiple of device pixels, the last button
+      // of each row sometimes gets pushed to the next row, depending on the
+      // panel and button widths.
+      // This is likely because the clientWidth getter rounds the value, but
+      // the panel's border width is not an integer.
+      // As a workaround, decrement the width if the scale is not an integer.
+      let scale = window.windowUtils.screenPixelsPerCSSPixel;
+      if (Math.floor(scale) != scale) {
+        --buttonsWidth;
+      }
 
-    let enginesPerRow = Math.floor(buttonsWidth / this.buttonWidth);
-    // There will be an empty area of:
-    //   buttonsWidth - enginesPerRow * this.buttonWidth  px
-    // at the end of each row.
+      // If the header string is very long, then the searchbar buttons will
+      // overflow their container unless max-width is set.
+      this.buttons.style.setProperty("max-width", `${buttonsWidth}px`);
+
+      // In very narrow windows, we should always have at least one button
+      // per row.
+      buttonsWidth = Math.max(buttonsWidth, this.buttonWidth);
 
-    // If the <div> with the list of search engines doesn't have
-    // a fixed height, the panel will be sized incorrectly, causing the bottom
-    // of the suggestion <tree> to be hidden.
-    let rowCount = Math.ceil(oneOffCount / enginesPerRow);
-    let height = rowCount * this.buttonHeight;
-    this.buttons.style.setProperty("height", `${height}px`);
+      let enginesPerRow = Math.floor(buttonsWidth / this.buttonWidth);
+      // There will be an empty area of:
+      //   buttonsWidth - enginesPerRow * this.buttonWidth  px
+      // at the end of each row.
+
+      // If the <div> with the list of search engines doesn't have
+      // a fixed height, the panel will be sized incorrectly, causing the bottom
+      // of the suggestion <tree> to be hidden.
+      let rowCount = Math.ceil(oneOffCount / enginesPerRow);
+      let height = rowCount * this.buttonHeight;
+      this.buttons.style.setProperty("height", `${height}px`);
+    }
     // Ensure we can refer to the settings buttons by ID:
     let origin = this.telemetryOrigin;
     this.settingsButton.id = origin + "-anon-search-settings";
     this.settingsButtonCompact.id = origin + "-anon-search-settings-compact";
 
     for (let i = 0; i < engines.length; ++i) {
       let engine = engines[i];
       let button = document.createXULElement("button");