author | Cosmin Sabou <csabou@mozilla.com> |
Fri, 16 Feb 2018 12:15:38 +0200 | |
changeset 404143 | f01d1def46fb53a6523768c6e9188e66b89e664e |
parent 404133 | 9eaebbcc33fd3824876db1b8b33750e997c02f7b (current diff) |
parent 404061 | 0adb6b91b758fc7e45bd0476a2fbadc913adeee0 (diff) |
child 404144 | 941681a0ddc64f46dda9c2e69ea36a78bc307dee |
child 404204 | c76cfa405b0e4b96e290d440cecdae8691f077de |
push id | 99942 |
push user | nbeleuzu@mozilla.com |
push date | Fri, 16 Feb 2018 11:16:06 +0000 |
treeherder | mozilla-inbound@8cf35a5cc077 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 60.0a1 |
first release with | nightly linux32
f01d1def46fb
/
60.0a1
/
20180216104033
/
files
nightly linux64
f01d1def46fb
/
60.0a1
/
20180216104033
/
files
nightly mac
f01d1def46fb
/
60.0a1
/
20180216104033
/
files
nightly win32
f01d1def46fb
/
60.0a1
/
20180216104033
/
files
nightly win64
f01d1def46fb
/
60.0a1
/
20180216104033
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
60.0a1
/
20180216104033
/
pushlog to previous
nightly linux64
60.0a1
/
20180216104033
/
pushlog to previous
nightly mac
60.0a1
/
20180216104033
/
pushlog to previous
nightly win32
60.0a1
/
20180216104033
/
pushlog to previous
nightly win64
60.0a1
/
20180216104033
/
pushlog to previous
|
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1249,28 +1249,16 @@ var gBrowserInit = { remoteType, sameProcessAsFrameLoader }); gUIDensity.init(); if (AppConstants.CAN_DRAW_IN_TITLEBAR) { gDragSpaceObserver.init(); } - - // Hack to ensure that the about:home favicon is loaded - // instantaneously, to avoid flickering and improve perceived performance. - this._callWithURIToLoad(uriToLoad => { - if (uriToLoad == "about:home") { - gBrowser.setIcon(gBrowser.selectedTab, "chrome://branding/content/icon32.png"); - } else if (uriToLoad == "about:privatebrowsing") { - gBrowser.setIcon(gBrowser.selectedTab, "chrome://browser/skin/privatebrowsing/favicon.svg"); - } - }); - - this._setInitialFocus(); }, onLoad() { gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver); Services.obs.addObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed"); window.addEventListener("AppCommand", HandleAppCommandEvent, true); @@ -1361,16 +1349,28 @@ var gBrowserInit = { try { gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToOpen); } catch (e) { Cu.reportError(e); } } + this._setInitialFocus(); + + // Hack to ensure that the about:home favicon is loaded + // instantaneously, to avoid flickering and improve perceived performance. + this._uriToLoadPromise.then(uriToLoad => { + if (uriToLoad == "about:home") { + gBrowser.setIcon(gBrowser.selectedTab, "chrome://branding/content/icon32.png"); + } else if (uriToLoad == "about:privatebrowsing") { + gBrowser.setIcon(gBrowser.selectedTab, "chrome://browser/skin/privatebrowsing/favicon.svg"); + } + }); + // Wait until chrome is painted before executing code not critical to making the window visible this._boundDelayedStartup = this._delayedStartup.bind(this); window.addEventListener("MozAfterPaint", this._boundDelayedStartup); this._loadHandled = true; }, _cancelDelayedStartup() { @@ -1587,25 +1587,19 @@ var gBrowserInit = { let initialBrowser = gBrowser.selectedBrowser; mm.addMessageListener("Browser:FirstNonBlankPaint", function onFirstNonBlankPaint() { mm.removeMessageListener("Browser:FirstNonBlankPaint", onFirstNonBlankPaint); initialBrowser.removeAttribute("blank"); }); - // To prevent flickering of the urlbar-history-dropmarker in the general - // case, the urlbar has the 'focused' attribute set by default. - // If we are not fully sure the urlbar will be focused in this window, - // we should remove the attribute before first paint. - let shouldRemoveFocusedAttribute = true; - this._callWithURIToLoad(uriToLoad => { + this._uriToLoadPromise.then(uriToLoad => { if ((isBlankPageURL(uriToLoad) || uriToLoad == "about:privatebrowsing") && focusAndSelectUrlBar()) { - shouldRemoveFocusedAttribute = false; return; } if (gBrowser.selectedBrowser.isRemoteBrowser) { // If the initial browser is remote, in order to optimize for first paint, // we'll defer switching focus to that browser until it has painted. firstBrowserPaintDeferred.promise.then(() => { // If focus didn't move while we were waiting for first paint, we're okay @@ -1615,22 +1609,20 @@ var gBrowserInit = { } }); } else { // If the initial browser is not remote, we can focus the browser // immediately with no paint performance impact. gBrowser.selectedBrowser.focus(); } }); - if (shouldRemoveFocusedAttribute) - gURLBar.removeAttribute("focused"); }, _handleURIToLoad() { - this._callWithURIToLoad(uriToLoad => { + this._uriToLoadPromise.then(uriToLoad => { if (!uriToLoad || uriToLoad == "about:blank") { return; } // We don't check if uriToLoad is a XULElement because this case has // already been handled before first paint, and the argument cleared. if (uriToLoad instanceof Ci.nsIArray) { let count = uriToLoad.length; @@ -1739,59 +1731,47 @@ var gBrowserInit = { ChromeUtils.import("resource:///modules/DownloadsTaskbar.jsm", {}) .DownloadsTaskbar.registerIndicator(window); } catch (ex) { Cu.reportError(ex); } }, {timeout: 10000}); }, - // Returns the URI(s) to load at startup if it is immediately known, or a - // promise resolving to the URI to load. + // Returns the URI(s) to load at startup. get _uriToLoadPromise() { delete this._uriToLoadPromise; - return this._uriToLoadPromise = function() { + return this._uriToLoadPromise = new Promise(resolve => { // window.arguments[0]: URI to load (string), or an nsIArray of // nsISupportsStrings to load, or a xul:tab of // a tabbrowser, which will be replaced by this // window (for this case, all other arguments are // ignored). if (!window.arguments || !window.arguments[0]) { - return null; + resolve(null); + return; } let uri = window.arguments[0]; let defaultArgs = Cc["@mozilla.org/browser/clh;1"] .getService(Ci.nsIBrowserHandler) .defaultArgs; // If the given URI is different from the homepage, we want to load it. if (uri != defaultArgs) { - return uri; + resolve(uri); + return; } // The URI appears to be the the homepage. We want to load it only if // session restore isn't about to override the homepage. - let willOverride = SessionStartup.willOverrideHomepage; - if (!(willOverride instanceof Promise)) { - return willOverride ? null : uri; - } - return willOverride.then(willOverrideHomepage => - willOverrideHomepage ? null : uri); - }(); - }, - - // Calls the given callback with the URI to load at startup. - // Synchronously if possible, or after _uriToLoadPromise resolves otherwise. - _callWithURIToLoad(callback) { - let uriToLoad = this._uriToLoadPromise; - if (uriToLoad instanceof Promise) - uriToLoad.then(callback); - else - callback(uriToLoad); + SessionStartup.willOverrideHomepagePromise.then(willOverrideHomepage => { + resolve(willOverrideHomepage ? null : uri); + }); + }); }, onUnload() { gUIDensity.uninit(); if (AppConstants.CAN_DRAW_IN_TITLEBAR) { gDragSpaceObserver.uninit(); }
--- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -768,17 +768,16 @@ cui-areatype="toolbar" aboutHomeOverrideTooltip="&abouthome.pageTitle;"/> <toolbarspring cui-areatype="toolbar" class="chromeclass-toolbar-additional"/> <toolbaritem id="urlbar-container" flex="400" persist="width" removable="false" class="chromeclass-location" overflows="false"> <textbox id="urlbar" flex="1" placeholder="&urlbar.placeholder2;" - focused="true" type="autocomplete" autocompletesearch="unifiedcomplete" autocompletesearchparam="enable-actions" autocompletepopup="PopupAutoCompleteRichResult" completeselectedindex="true" shrinkdelay="250" tabscrolling="true" newlines="stripsurroundingwhitespace"
--- a/browser/base/content/test/performance/browser_startup_flicker.js +++ b/browser/base/content/test/performance/browser_startup_flicker.js @@ -31,22 +31,35 @@ add_task(async function() { alreadyFocused = true; // This is likely an issue caused by the test harness, but log it anyway. todo(false, "the window should be focused at first paint, " + rects.toSource()); continue; } rects = rects.filter(rect => { + let inRange = (val, min, max) => min <= val && val <= max; let width = frame.width; let exceptions = [ - /** - * Nothing here! Please don't add anything new! - */ + {name: "bug 1403648 - urlbar down arrow shouldn't flicker", + condition: r => // 5x9px area, sometimes less at the end of the opacity transition + inRange(r.h, 3, 5) && inRange(r.w, 7, 9) && + inRange(r.y1, 40, 80) && // in the toolbar + // at ~80% of the window width + inRange(r.x1, width * .75, width * .9) + }, + + {name: "bug 1403648 - urlbar should be focused at first paint", + condition: r => inRange(r.y2, 60, 80) && // in the toolbar + // taking 50% to 75% of the window width + inRange(r.w, width * .5, width * .75) && + // starting at 15 to 25% of the window width + inRange(r.x1, width * .15, width * .25) + }, ]; let rectText = `${rect.toSource()}, window width: ${width}`; for (let e of exceptions) { if (e.condition(rect)) { todo(false, e.name + ", " + rectText); return false; }
--- a/browser/base/content/test/performance/browser_windowopen_flicker.js +++ b/browser/base/content/test/performance/browser_windowopen_flicker.js @@ -80,26 +80,54 @@ add_task(async function() { continue; } ignoreTinyPaint = false; let rects = compareFrames(frame, previousFrame).filter(rect => { let inRange = (val, min, max) => min <= val && val <= max; let width = frame.width; + const spaceBeforeFirstTab = AppConstants.platform == "macosx" ? 100 : 0; + let inFirstTab = r => + inRange(r.x1, spaceBeforeFirstTab, spaceBeforeFirstTab + 50) && r.y1 < 30; + let exceptions = [ + {name: "bug 1403648 - urlbar down arrow shouldn't flicker", + condition: r => // 5x9px area, sometimes less at the end of the opacity transition + inRange(r.h, 3, 5) && inRange(r.w, 7, 9) && + inRange(r.y1, 40, 80) && // in the toolbar + // at ~80% of the window width + inRange(r.x1, width * .75, width * .9) + }, + + {name: "bug 1403648 - urlbar should be focused at first paint", + condition: r => inRange(r.y2, 60, 80) && // in the toolbar + // taking 50% to 75% of the window width + inRange(r.w, width * .5, width * .75) && + // starting at 15 to 25% of the window width + inRange(r.x1, width * .15, width * .25) + }, + {name: "bug 1421463 - reload toolbar icon shouldn't flicker", condition: r => r.h == 13 && inRange(r.w, 14, 16) && // icon size inRange(r.y1, 40, 80) && // in the toolbar // near the left side of the screen // The reload icon is shifted on devedition builds // where there's an additional devtools toolbar icon. AppConstants.MOZ_DEV_EDITION ? inRange(r.x1, 100, 120) : inRange(r.x1, 65, 100) }, + + {name: "bug 1401955 - about:home favicon should be visible at first paint", + condition: r => inFirstTab(r) && inRange(r.h, 14, 15) && inRange(r.w, 14, 15) + }, + + {name: "bug 1401955 - space for about:home favicon should be there at first paint", + condition: r => inFirstTab(r) && inRange(r.w, 60, 80) && inRange(r.h, 8, 15) + }, ]; let rectText = `${rect.toSource()}, window width: ${width}`; for (let e of exceptions) { if (e.condition(rect)) { todo(false, e.name + ", " + rectText); return false; }
--- a/browser/base/content/test/performance/browser_windowopen_reflows.js +++ b/browser/base/content/test/performance/browser_windowopen_reflows.js @@ -31,16 +31,22 @@ if (Services.appinfo.OS == "WINNT") { }, ); } if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") { EXPECTED_REFLOWS.push( { stack: [ + "select@chrome://global/content/bindings/textbox.xml", + "focusAndSelectUrlBar@chrome://browser/content/browser.js", + ], + }, + { + stack: [ "rect@chrome://browser/content/browser-tabsintitlebar.js", "_update@chrome://browser/content/browser-tabsintitlebar.js", "init@chrome://browser/content/browser-tabsintitlebar.js", "handleEvent@chrome://browser/content/tabbrowser.xml", ], // These numbers should only ever go down - never up. times: Services.appinfo.OS == "WINNT" ? 5 : 4, },
--- a/browser/components/sessionstore/nsISessionStartup.idl +++ b/browser/components/sessionstore/nsISessionStartup.idl @@ -31,24 +31,23 @@ interface nsISessionStartup: nsISupports /** * Determines whether automatic session restoration is enabled for this * launch of the browser. This does not include crash restoration, and will * return false if restoration will only be caused by a crash. */ boolean isAutomaticRestoreEnabled(); /** - * Returns a boolean or a promise that resolves to a boolean, indicating - * whether we will restore a session that ends up replacing the homepage. - * True guarantees that we'll restore a session; false means that we - * /probably/ won't do so. + * Returns a promise that resolves to a boolean, indicating whether we will + * restore a session that ends up replacing the homepage. True guarantees + * that we'll restore a session; false means that we /probably/ won't do so. * The browser uses this to avoid unnecessarily loading the homepage when * restoring a session. */ - readonly attribute jsval willOverrideHomepage; + readonly attribute jsval willOverrideHomepagePromise; /** * What type of session we're restoring. * NO_SESSION There is no data available from the previous session * RECOVER_SESSION The last session crashed. It will either be restored or * about:sessionrestore will be shown. * RESUME_SESSION The previous session should be restored at startup * DEFER_SESSION The previous session is fine, but it shouldn't be restored
--- a/browser/components/sessionstore/nsSessionStartup.js +++ b/browser/components/sessionstore/nsSessionStartup.js @@ -305,31 +305,30 @@ SessionStartup.prototype = { * @returns bool */ _willRestore() { return this._sessionType == Ci.nsISessionStartup.RECOVER_SESSION || this._sessionType == Ci.nsISessionStartup.RESUME_SESSION; }, /** - * Returns a boolean or a promise that resolves to a boolean, indicating - * whether we will restore a session that ends up replacing the homepage. - * True guarantees that we'll restore a session; false means that we - * /probably/ won't do so. + * Returns a promise that resolves to a boolean, indicating whether we will + * restore a session that ends up replacing the homepage. True guarantees + * that we'll restore a session; false means that we /probably/ won't do so. * The browser uses this to avoid unnecessarily loading the homepage when * restoring a session. */ - get willOverrideHomepage() { + get willOverrideHomepagePromise() { // If the session file hasn't been read yet and resuming the session isn't // enabled via prefs, go ahead and load the homepage. We may still replace // it when recovering from a crash, which we'll only know after reading the // session file, but waiting for that would delay loading the homepage in // the non-crash case. if (!this._initialState && !this._resumeSessionEnabled) { - return false; + return Promise.resolve(false); } return new Promise(resolve => { this.onceInitialized.then(() => { // If there are valid windows with not only pinned tabs, signal that we // will override the default homepage by restoring a session. resolve(this._willRestore() && this._initialState &&