Bug 1497975 - Prevent layouts during parse of browser.xhtml;r=Gijs,emilio
authorBrian Grinstead <bgrinstead@mozilla.com>
Thu, 11 Oct 2018 18:10:33 +0000
changeset 499191 bb7c6b3e49c79adb61ab85785e408b0e012b63bf
parent 499190 7a97fe41a34fabed6beeb3db2fc0a2c61623eeae
child 499192 0ff0cb5364283cb55240c42e476ca1e5458ec567
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, emilio
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 1497975 - Prevent layouts during parse of browser.xhtml;r=Gijs,emilio By hiding the documentElement with display:none and then waiting to show it until readystatechange, we can avoid inadvertently constructing XBL bindings as a result scripts running during parse like connectedCallback. This more closely matches XUL document behavior, where the initial layout doesn't happen until everything is parsed and loaded. It also lets us call gBrowserInit.onBeforeInitialXULLayout actually before layout happens. Differential Revision: https://phabricator.services.mozilla.com/D8297
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -65,17 +65,21 @@
         screenX="4" screenY="4"
-        persist="screenX screenY width height sizemode">
+        persist="screenX screenY width height sizemode"
+        hidden="true"
+        >
 # All JS files which are needed by browser.xul and other top level windows to
 # support MacOS specific features *must* go into the global-scripts.inc file so
 # that they can be shared with macWindow.inc.xul.
 #include global-scripts.inc
 <script type="application/javascript"
@@ -83,19 +87,24 @@ xmlns="http://www.w3.org/1999/xhtml"
   Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", this);
   Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser.js", this);
   window.onload = gBrowserInit.onLoad.bind(gBrowserInit);
   window.onunload = gBrowserInit.onUnload.bind(gBrowserInit);
   window.onclose = WindowIsClosing;
-  window.addEventListener("DOMContentLoaded",
-    gBrowserInit.onBeforeInitialXULLayout.bind(gBrowserInit), { once: true });
+  window.addEventListener("readystatechange", () => {
+    // We initially hide the window to prevent layouts during parse. This lets us
+    // avoid accidental XBL construction and better match browser.xul (see Bug 1497975).
+    gBrowserInit.onBeforeInitialXULLayout();
+    document.documentElement.removeAttribute("hidden");
+  }, { once: true, capture: true });
     gBrowserInit.onBeforeInitialXULLayout.bind(gBrowserInit), { once: true });
   // The listener of DOMContentLoaded must be set on window, rather than
   // document, because the window can go away before the event is fired.
   // In that case, we don't want to initialize anything, otherwise we
   // may be leaking things because they will never be destroyed after.