WIP: Bug 1708121, keep ticking after page load r=mstange

Differential Revision: https://phabricator.services.mozilla.com/D116040
This commit is contained in:
Olli Pettay 2021-05-27 16:08:04 +00:00
parent 2e841d22cb
commit ee2d66f98b
4 changed files with 57 additions and 0 deletions

View File

@ -202,6 +202,8 @@ class nsDOMNavigationTiming final : public mozilla::RelativeTimeline {
return mDocShellHasBeenActiveSinceNavigationStart;
}
mozilla::TimeStamp LoadEventEnd() { return mLoadEventEnd; }
private:
friend class nsDocShell;
nsDOMNavigationTiming(nsDocShell* aDocShell, nsDOMNavigationTiming* aOther);

View File

@ -51,6 +51,7 @@
#include "nsContentUtils.h"
#include "mozilla/PendingAnimationTracker.h"
#include "mozilla/PendingFullscreenEvent.h"
#include "mozilla/dom/PerformanceMainThread.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs_apz.h"
#include "mozilla/StaticPrefs_gfx.h"
@ -84,6 +85,7 @@
#include "mozilla/TimelineConsumers.h"
#include "nsAnimationManager.h"
#include "nsDisplayList.h"
#include "nsDOMNavigationTiming.h"
#include "nsTransitionManager.h"
#if defined(MOZ_WIDGET_ANDROID)
@ -1131,6 +1133,7 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
mNeedToUpdateIntersectionObservations(false),
mInNormalTick(false),
mAttemptedExtraTickSinceLastVsync(false),
mHasExceededAfterLoadTickPeriod(false),
mWarningThreshold(REFRESH_WAIT_WARNING) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mPresContext,
@ -1735,6 +1738,43 @@ bool nsRefreshDriver::
return TimeStamp::Now() <= mBeforeFirstContentfulPaintTimerRunningLimit;
}
bool nsRefreshDriver::ShouldKeepTimerRunningAfterPageLoad() {
if (mHasExceededAfterLoadTickPeriod ||
!StaticPrefs::layout_keep_ticking_after_load_ms() || mThrottled ||
mTestControllingRefreshes || !XRE_IsContentProcess() ||
!mPresContext->Document()->IsTopLevelContentDocument() ||
gfxPlatform::IsInLayoutAsapMode()) {
// Make the next check faster.
mHasExceededAfterLoadTickPeriod = true;
return false;
}
nsPIDOMWindowInner* innerWindow = mPresContext->Document()->GetInnerWindow();
if (innerWindow) {
if (PerformanceMainThread* perf = static_cast<PerformanceMainThread*>(
innerWindow->GetPerformance())) {
nsDOMNavigationTiming* timing = perf->GetDOMTiming();
if (timing) {
TimeStamp loadend = timing->LoadEventEnd();
if (loadend) {
// Keep ticking after the page load for some time.
bool retval =
(loadend +
TimeDuration::FromMilliseconds(
StaticPrefs::layout_keep_ticking_after_load_ms())) >
TimeStamp::Now();
if (!retval) {
mHasExceededAfterLoadTickPeriod = true;
}
return retval;
}
}
}
}
return false;
}
nsRefreshDriver::ObserverArray& nsRefreshDriver::ArrayFor(
FlushType aFlushType) {
switch (aFlushType) {
@ -2107,6 +2147,11 @@ void nsRefreshDriver::Tick(VsyncId aId, TimeStamp aNowTime,
"RefreshDriverTick waiting for first contentful paint", GRAPHICS,
MarkerInnerWindowIdFromDocShell(GetDocShell(mPresContext)), Tracing,
"Paint");
} else if (ShouldKeepTimerRunningAfterPageLoad()) {
PROFILER_MARKER(
"RefreshDriverTick after page load", GRAPHICS,
MarkerInnerWindowIdFromDocShell(GetDocShell(mPresContext)), Tracing,
"Paint");
} else {
StopTimer();
}

View File

@ -480,6 +480,7 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
uint32_t ObserverCount() const;
bool HasImageRequests() const;
bool ShouldKeepTimerRunningWhileWaitingForFirstContentfulPaint();
bool ShouldKeepTimerRunningAfterPageLoad();
ObserverArray& ArrayFor(mozilla::FlushType aFlushType);
// Trigger a refresh immediately, if haven't been disconnected or frozen.
void DoRefresh();
@ -590,6 +591,8 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
// vsync and thus shouldn't allow another.
bool mAttemptedExtraTickSinceLastVsync : 1;
bool mHasExceededAfterLoadTickPeriod : 1;
// Number of seconds that the refresh driver is blocked waiting for a
// compositor transaction to be completed before we append a note to the gfx
// critical log. The number is doubled every time the threshold is hit.

View File

@ -7331,6 +7331,13 @@
value: true
mirror: always
# If > 0, nsRefreshDriver will keep ticking this amount of milliseconds after
# top level page load.
- name: layout.keep_ticking_after_load_ms
type: uint32_t
value: 1000
mirror: always
# Is layout of CSS outline-style:auto enabled?
- name: layout.css.outline-style-auto.enabled
type: bool