Bug 1541229, higher minimum idle period during page load, r=farre

Differential Revision: https://phabricator.services.mozilla.com/D37908

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Olli Pettay 2019-07-16 12:07:49 +00:00
Родитель 81469e4765
Коммит 9eeb5dab4f
3 изменённых файлов: 81 добавлений и 0 удалений

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

@ -346,6 +346,9 @@ namespace dom {
typedef nsTArray<Link*> LinkArray;
AutoTArray<Document*, 8>* Document::sLoadingForegroundTopLevelContentDocument =
nullptr;
static LazyLogModule gDocumentLeakPRLog("DocumentLeak");
static LazyLogModule gCspPRLog("CSP");
LazyLogModule gUserInteractionPRLog("UserInteraction");
@ -1667,6 +1670,8 @@ Document::~Document() {
NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document");
if (IsTopLevelContentDocument()) {
RemoveToplevelLoadingDocument(this);
// don't report for about: pages
if (!IsAboutPage()) {
// Record the page load
@ -11152,6 +11157,14 @@ void Document::SetReadyStateInternal(ReadyState rs,
return;
}
if (IsTopLevelContentDocument()) {
if (rs == READYSTATE_LOADING) {
AddToplevelLoadingDocument(this);
} else if (rs == READYSTATE_COMPLETE) {
RemoveToplevelLoadingDocument(this);
}
}
if (updateTimingInformation && READYSTATE_LOADING == rs) {
mLoadingTimeStamp = mozilla::TimeStamp::Now();
}
@ -15783,5 +15796,57 @@ void Document::SetIsInitialDocument(bool aIsInitialDocument) {
}
}
void Document::AddToplevelLoadingDocument(Document* aDoc) {
MOZ_ASSERT(aDoc && aDoc->IsTopLevelContentDocument());
// Currently we're interested in foreground documents only, so bail out early.
if (aDoc->IsInBackgroundWindow() || !XRE_IsContentProcess()) {
return;
}
if (!sLoadingForegroundTopLevelContentDocument) {
sLoadingForegroundTopLevelContentDocument = new AutoTArray<Document*, 8>();
}
if (!sLoadingForegroundTopLevelContentDocument->Contains(aDoc)) {
sLoadingForegroundTopLevelContentDocument->AppendElement(aDoc);
}
}
void Document::RemoveToplevelLoadingDocument(Document* aDoc) {
MOZ_ASSERT(aDoc && aDoc->IsTopLevelContentDocument());
if (sLoadingForegroundTopLevelContentDocument) {
sLoadingForegroundTopLevelContentDocument->RemoveElement(aDoc);
if (sLoadingForegroundTopLevelContentDocument->IsEmpty()) {
delete sLoadingForegroundTopLevelContentDocument;
sLoadingForegroundTopLevelContentDocument = nullptr;
}
}
}
bool Document::HasRecentlyStartedForegroundLoads() {
if (!sLoadingForegroundTopLevelContentDocument) {
return false;
}
for (size_t i = 0; i < sLoadingForegroundTopLevelContentDocument->Length();
++i) {
Document* doc = sLoadingForegroundTopLevelContentDocument->ElementAt(i);
// A page loaded in foreground could be in background now.
if (!doc->IsInBackgroundWindow()) {
nsPIDOMWindowInner* win = doc->GetInnerWindow();
if (win) {
Performance* perf = win->GetPerformance();
if (perf && perf->Now() < 5000) {
return true;
}
}
}
}
// Didn't find any loading foreground documents, just clear the array.
delete sLoadingForegroundTopLevelContentDocument;
sLoadingForegroundTopLevelContentDocument = nullptr;
return false;
}
} // namespace dom
} // namespace mozilla

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

@ -4119,6 +4119,8 @@ class Document : public nsINode,
bool InRDMPane() const { return mInRDMPane; }
void SetInRDMPane(bool aInRDMPane) { mInRDMPane = aInRDMPane; }
static bool HasRecentlyStartedForegroundLoads();
protected:
void DoUpdateSVGUseElementShadowTrees();
@ -4391,6 +4393,10 @@ class Document : public nsINode,
already_AddRefed<nsIChannel> CreateDummyChannelForCookies(
nsIURI* aContentURI);
void AddToplevelLoadingDocument(Document* aDoc);
void RemoveToplevelLoadingDocument(Document* aDoc);
static AutoTArray<Document*, 8>* sLoadingForegroundTopLevelContentDocument;
nsCOMPtr<nsIReferrerInfo> mPreloadReferrerInfo;
nsCOMPtr<nsIReferrerInfo> mReferrerInfo;

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

@ -8,6 +8,7 @@
#include "mozilla/Maybe.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Document.h"
#include "nsRefreshDriver.h"
#include "nsThreadUtils.h"
@ -20,6 +21,7 @@ static const double kLongIdlePeriodMS = 50.0;
// expect to become busy again be:
// now + kMinIdlePeriodMS + layout.idle_period.time_limit
static const double kMinIdlePeriodMS = 3.0;
static const double kMinIdlePeriodDuringLoadMS = 12.0;
static const uint32_t kMaxTimerThreadBound = 5; // milliseconds
static const uint32_t kMaxTimerThreadBoundClamp = 15; // milliseconds
@ -46,6 +48,14 @@ MainThreadIdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline) {
(now >= (currentGuess - minIdlePeriod)) ||
currentGuess < mLastIdleDeadline;
// During page load use higher minimum idle period.
if (!busySoon && XRE_IsContentProcess() &&
mozilla::dom::Document::HasRecentlyStartedForegroundLoads()) {
TimeDuration minIdlePeriod =
TimeDuration::FromMilliseconds(kMinIdlePeriodDuringLoadMS);
busySoon = (now >= (currentGuess - minIdlePeriod));
}
if (!busySoon) {
*aIdleDeadline = mLastIdleDeadline = currentGuess;
}