Bug 1373814 - Add new probe to measure start-up input latency. data-r=francois r=francois,smaug

For parent process, users may expect the UI is interactable after they saw the
first tab has restored/shown.
So this patch added a new topic "sessionstore-one-or-no-tab-restored" which
represents the parent process has finished a tab restoring. If there is nothing
to restore, it is effectively equal to "sessionstore-windows-restored".

For centent processes, users may expect web content is interactable when the
top-level-content-document has finished loading, which is different from the
parent case.

MozReview-Commit-ID: AtEUW80Ea6n

--HG--
extra : rebase_source : d920975bf95545ea9e3127d3f570b814fe301be9
This commit is contained in:
Wei-Cheng Pan 2017-08-08 17:54:13 +08:00
Родитель 3cb51cb410
Коммит 83f77707b7
4 изменённых файлов: 75 добавлений и 0 удалений

Просмотреть файл

@ -971,6 +971,8 @@ var SessionStoreInternal = {
SessionStoreInternal.restoreNextTab();
this._sendTabRestoredNotification(tab, data.isRemotenessUpdate);
Services.obs.notifyObservers(null, "sessionstore-one-or-no-tab-restored");
break;
case "SessionStore:crashedTabRevived":
// The browser was revived by navigating to a different page
@ -1149,6 +1151,7 @@ var SessionStoreInternal = {
// Nothing to restore now, notify observers things are complete.
Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED);
Services.obs.notifyObservers(null, "sessionstore-one-or-no-tab-restored");
this._deferredAllWindowsRestored.resolve();
} else {
TelemetryTimestamps.add("sessionRestoreRestoring");
@ -1168,6 +1171,7 @@ var SessionStoreInternal = {
} else {
// Nothing to restore, notify observers things are complete.
Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED);
Services.obs.notifyObservers(null, "sessionstore-one-or-no-tab-restored");
this._deferredAllWindowsRestored.resolve();
}
// this window was opened by _openWindowWithState

Просмотреть файл

@ -560,6 +560,8 @@ mozilla::LazyLogModule PresShell::gLog("PresShell");
mozilla::TimeStamp PresShell::sLastInputCreated;
mozilla::TimeStamp PresShell::sLastInputProcessed;
bool PresShell::sProcessInteractable = false;
#ifdef DEBUG
static void
VerifyStyleTree(nsPresContext* aPresContext, nsFrameManager* aFrameManager)
@ -1017,6 +1019,9 @@ PresShell::Init(nsIDocument* aDocument,
#endif
os->AddObserver(this, "memory-pressure", false);
os->AddObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC, false);
if (XRE_IsParentProcess() && !sProcessInteractable) {
os->AddObserver(this, "sessionstore-one-or-no-tab-restored", false);
}
}
}
@ -1245,6 +1250,9 @@ PresShell::Destroy()
#endif
os->RemoveObserver(this, "memory-pressure");
os->RemoveObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC);
if (XRE_IsParentProcess()) {
os->RemoveObserver(this, "sessionstore-one-or-no-tab-restored");
}
}
}
@ -8281,6 +8289,32 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent,
double lastMillis = (sLastInputProcessed - sLastInputCreated).ToMilliseconds();
Telemetry::Accumulate(Telemetry::INPUT_EVENT_RESPONSE_COALESCED_MS,
lastMillis);
if (MOZ_UNLIKELY(!sProcessInteractable)) {
// For content process, we use the ready state of
// top-level-content-document to know if the process has finished the
// start-up.
// For parent process, see the topic
// 'sessionstore-one-or-no-tab-restored' in PresShell::Observe.
if (XRE_IsContentProcess() &&
mDocument && mDocument->IsTopLevelContentDocument()) {
switch (mDocument->GetReadyStateEnum()) {
case nsIDocument::READYSTATE_INTERACTIVE:
case nsIDocument::READYSTATE_COMPLETE:
sProcessInteractable = true;
break;
default:
break;
}
}
}
if (MOZ_LIKELY(sProcessInteractable)) {
Telemetry::Accumulate(Telemetry::INPUT_EVENT_RESPONSE_POST_STARTUP_MS,
lastMillis);
} else {
Telemetry::Accumulate(Telemetry::INPUT_EVENT_RESPONSE_STARTUP_MS,
lastMillis);
}
}
sLastInputCreated = aEvent->mTimeStamp;
} else if (aEvent->mTimeStamp < sLastInputCreated) {
@ -9719,6 +9753,19 @@ PresShell::Observe(nsISupports* aSubject,
return NS_OK;
}
// For parent process, user may expect the UI is interactable after a
// tab (previously opened page or home page) has restored.
if (!nsCRT::strcmp(aTopic, "sessionstore-one-or-no-tab-restored")) {
MOZ_ASSERT(XRE_IsParentProcess());
sProcessInteractable = true;
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os) {
os->RemoveObserver(this, "sessionstore-one-or-no-tab-restored");
}
return NS_OK;
}
NS_WARNING("unrecognized topic in PresShell::Observe");
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -902,6 +902,8 @@ protected:
static mozilla::TimeStamp sLastInputCreated;
static mozilla::TimeStamp sLastInputProcessed;
static bool sProcessInteractable;
};
} // namespace mozilla

Просмотреть файл

@ -6520,6 +6520,28 @@
"releaseChannelCollection": "opt-out",
"description": "Time (ms) from the Input event being created to the end of it being handled, but with overlapping events coalesced."
},
"INPUT_EVENT_RESPONSE_STARTUP_MS": {
"record_in_processes": ["main", "content"],
"alert_emails": ["wpan@mozilla.com"],
"bug_numbers": [1373814],
"expires_in_version": "61",
"kind": "exponential",
"high": 10000,
"n_buckets": 50,
"releaseChannelCollection": "opt-out",
"description": "Time (ms) from the Input event being created to the end of it being handled, but with overlapping events coalesced, which happens before the process is ready for interaction."
},
"INPUT_EVENT_RESPONSE_POST_STARTUP_MS": {
"record_in_processes": ["main", "content"],
"alert_emails": ["wpan@mozilla.com"],
"bug_numbers": [1373814],
"expires_in_version": "61",
"kind": "exponential",
"high": 10000,
"n_buckets": 50,
"releaseChannelCollection": "opt-out",
"description": "Time (ms) from the Input event being created to the end of it being handled, but with overlapping events coalesced, which happens after the process is ready for interaction."
},
"LOAD_INPUT_EVENT_RESPONSE_MS": {
"record_in_processes": ["main", "content"],
"alert_emails": ["perf-telemetry-alerts@mozilla.com"],