Commit 08df7ba8 authored by Hajime Hoshi's avatar Hajime Hoshi Committed by Commit Bot

BackForwardCache Record requestAnimationFrame times after BFcache restores

This CL adds new metrics to record the timing on requestAnimationFrame
three times after the page is restored from BFcache. These values can be
good approximation for the first paint after BFcache restores, and we
want to confirm this.

BUG: 1133333
BUG: 1152688
Change-Id: Ib7fe363bf6ac20f07308bd90eb940530fcd49df1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2523133
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarSteven Holte <holte@chromium.org>
Reviewed-by: default avatarNicolás Peña Moreno <npm@chromium.org>
Reviewed-by: default avatarAnnie Sullivan <sullivan@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#830919}
parent 2d0cae27
...@@ -12,6 +12,12 @@ namespace internal { ...@@ -12,6 +12,12 @@ namespace internal {
const char kHistogramFirstPaintAfterBackForwardCacheRestore[] = const char kHistogramFirstPaintAfterBackForwardCacheRestore[] =
"PageLoad.PaintTiming.NavigationToFirstPaint.AfterBackForwardCacheRestore"; "PageLoad.PaintTiming.NavigationToFirstPaint.AfterBackForwardCacheRestore";
const char kHistogramFirstRequestAnimationFrameAfterBackForwardCacheRestore[] =
"PageLoad.PaintTiming.NavigationToFirstPaint.BFCachePolyfillFirst";
const char kHistogramSecondRequestAnimationFrameAfterBackForwardCacheRestore[] =
"PageLoad.PaintTiming.NavigationToFirstPaint.BFCachePolyfillSecond";
const char kHistogramThirdRequestAnimationFrameAfterBackForwardCacheRestore[] =
"PageLoad.PaintTiming.NavigationToFirstPaint.BFCachePolyfillThird";
const char kHistogramFirstInputDelayAfterBackForwardCacheRestore[] = const char kHistogramFirstInputDelayAfterBackForwardCacheRestore[] =
"PageLoad.InteractiveTiming.FirstInputDelay.AfterBackForwardCacheRestore"; "PageLoad.InteractiveTiming.FirstInputDelay.AfterBackForwardCacheRestore";
extern const char extern const char
...@@ -97,6 +103,27 @@ void BackForwardCachePageLoadMetricsObserver:: ...@@ -97,6 +103,27 @@ void BackForwardCachePageLoadMetricsObserver::
} }
} }
void BackForwardCachePageLoadMetricsObserver::
OnRequestAnimationFramesAfterBackForwardCacheRestoreInPage(
const page_load_metrics::mojom::BackForwardCacheTiming& timing) {
auto request_animation_frames =
timing.request_animation_frames_after_back_forward_cache_restore;
DCHECK_EQ(request_animation_frames.size(), 3u);
PAGE_LOAD_HISTOGRAM(
internal::
kHistogramFirstRequestAnimationFrameAfterBackForwardCacheRestore,
request_animation_frames[0]);
PAGE_LOAD_HISTOGRAM(
internal::
kHistogramSecondRequestAnimationFrameAfterBackForwardCacheRestore,
request_animation_frames[1]);
PAGE_LOAD_HISTOGRAM(
internal::
kHistogramThirdRequestAnimationFrameAfterBackForwardCacheRestore,
request_animation_frames[2]);
}
void BackForwardCachePageLoadMetricsObserver:: void BackForwardCachePageLoadMetricsObserver::
OnFirstInputAfterBackForwardCacheRestoreInPage( OnFirstInputAfterBackForwardCacheRestoreInPage(
const page_load_metrics::mojom::BackForwardCacheTiming& timing, const page_load_metrics::mojom::BackForwardCacheTiming& timing,
......
...@@ -35,6 +35,8 @@ class BackForwardCachePageLoadMetricsObserver ...@@ -35,6 +35,8 @@ class BackForwardCachePageLoadMetricsObserver
void OnFirstPaintAfterBackForwardCacheRestoreInPage( void OnFirstPaintAfterBackForwardCacheRestoreInPage(
const page_load_metrics::mojom::BackForwardCacheTiming& timing, const page_load_metrics::mojom::BackForwardCacheTiming& timing,
size_t index) override; size_t index) override;
void OnRequestAnimationFramesAfterBackForwardCacheRestoreInPage(
const page_load_metrics::mojom::BackForwardCacheTiming& timing) override;
void OnFirstInputAfterBackForwardCacheRestoreInPage( void OnFirstInputAfterBackForwardCacheRestoreInPage(
const page_load_metrics::mojom::BackForwardCacheTiming& timing, const page_load_metrics::mojom::BackForwardCacheTiming& timing,
size_t index) override; size_t index) override;
......
...@@ -375,6 +375,13 @@ class PageLoadMetricsObserver { ...@@ -375,6 +375,13 @@ class PageLoadMetricsObserver {
const mojom::BackForwardCacheTiming& timing, const mojom::BackForwardCacheTiming& timing,
size_t index) {} size_t index) {}
// This is called several times on requestAnimationFrame after the page is
// restored from the back-forward cache. The number of the calls is hard-
// coded as WebPerformance::
// kRequestAnimationFramesToRecordAfterBackForwardCacheRestore.
virtual void OnRequestAnimationFramesAfterBackForwardCacheRestoreInPage(
const mojom::BackForwardCacheTiming& timing) {}
// Unlike other paint callbacks, OnFirstMeaningfulPaintInMainFrameDocument is // Unlike other paint callbacks, OnFirstMeaningfulPaintInMainFrameDocument is
// tracked per document, and is reported for the main frame document only. // tracked per document, and is reported for the main frame document only.
virtual void OnFirstMeaningfulPaintInMainFrameDocument( virtual void OnFirstMeaningfulPaintInMainFrameDocument(
......
...@@ -141,6 +141,18 @@ void DispatchEventsAfterBackForwardCacheRestore( ...@@ -141,6 +141,18 @@ void DispatchEventsAfterBackForwardCacheRestore(
i); i);
} }
auto request_animation_frames =
new_timings[i]
->request_animation_frames_after_back_forward_cache_restore;
if (request_animation_frames.size() == 3 &&
(i >= last_timings.size() ||
last_timings[i]
->request_animation_frames_after_back_forward_cache_restore
.empty())) {
observer->OnRequestAnimationFramesAfterBackForwardCacheRestoreInPage(
*new_timings[i]);
}
auto first_input_delay = auto first_input_delay =
new_timings[i]->first_input_delay_after_back_forward_cache_restore; new_timings[i]->first_input_delay_after_back_forward_cache_restore;
if (first_input_delay.has_value() && if (first_input_delay.has_value() &&
......
...@@ -353,6 +353,10 @@ struct BackForwardCacheTiming { ...@@ -353,6 +353,10 @@ struct BackForwardCacheTiming {
// is restored from the back-forward cache. // is restored from the back-forward cache.
mojo_base.mojom.TimeDelta first_paint_after_back_forward_cache_restore; mojo_base.mojom.TimeDelta first_paint_after_back_forward_cache_restore;
// Times on requestAnimationFrame when the page is restored from the back-
// forward cache.
array<mojo_base.mojom.TimeDelta> request_animation_frames_after_back_forward_cache_restore;
// Queueing Time of the first click, tap, key press, cancellable touchstart, // Queueing Time of the first click, tap, key press, cancellable touchstart,
// or pointer down followed by a pointer up after the time when the page is // or pointer down followed by a pointer up after the time when the page is
// restored from the back-forward cache. // restored from the back-forward cache.
......
...@@ -528,6 +528,13 @@ MetricsRenderFrameObserver::Timing MetricsRenderFrameObserver::GetTiming() ...@@ -528,6 +528,13 @@ MetricsRenderFrameObserver::Timing MetricsRenderFrameObserver::GetTiming()
->first_paint_after_back_forward_cache_restore = ->first_paint_after_back_forward_cache_restore =
ClampDelta(first_paint, navigation_start); ClampDelta(first_paint, navigation_start);
} }
for (double raf : restore_timing.request_animation_frames) {
if (!raf)
break;
back_forward_cache_timing
->request_animation_frames_after_back_forward_cache_restore
.push_back(ClampDelta(raf, navigation_start));
}
if (first_input_delay.has_value()) { if (first_input_delay.has_value()) {
back_forward_cache_timing back_forward_cache_timing
->first_input_delay_after_back_forward_cache_restore = ->first_input_delay_after_back_forward_cache_restore =
......
...@@ -47,9 +47,17 @@ class WindowPerformance; ...@@ -47,9 +47,17 @@ class WindowPerformance;
class WebPerformance { class WebPerformance {
public: public:
// The count to record the times on requestAnimationFrame after the page is
// restored from the back-forward cache.
static constexpr int
kRequestAnimationFramesToRecordAfterBackForwardCacheRestore = 3;
struct BackForwardCacheRestoreTiming { struct BackForwardCacheRestoreTiming {
double navigation_start = 0; double navigation_start = 0;
double first_paint = 0; double first_paint = 0;
std::array<double,
kRequestAnimationFramesToRecordAfterBackForwardCacheRestore>
request_animation_frames = {};
base::Optional<base::TimeDelta> first_input_delay; base::Optional<base::TimeDelta> first_input_delay;
}; };
......
...@@ -80,6 +80,11 @@ WebPerformance::BackForwardCacheRestore() const { ...@@ -80,6 +80,11 @@ WebPerformance::BackForwardCacheRestore() const {
MillisecondsToSeconds(restore_timings[i].navigation_start); MillisecondsToSeconds(restore_timings[i].navigation_start);
timings[i].first_paint = timings[i].first_paint =
MillisecondsToSeconds(restore_timings[i].first_paint); MillisecondsToSeconds(restore_timings[i].first_paint);
for (size_t j = 0; j < restore_timings[i].request_animation_frames.size();
j++) {
timings[i].request_animation_frames[j] =
MillisecondsToSeconds(restore_timings[i].request_animation_frames[j]);
}
timings[i].first_input_delay = restore_timings[i].first_input_delay; timings[i].first_input_delay = restore_timings[i].first_input_delay;
} }
return timings; return timings;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h"
...@@ -42,6 +43,47 @@ WindowPerformance* GetPerformanceInstance(LocalFrame* frame) { ...@@ -42,6 +43,47 @@ WindowPerformance* GetPerformanceInstance(LocalFrame* frame) {
} // namespace } // namespace
class RecodingTimeAfterBackForwardCacheRestoreFrameCallback
: public FrameCallback {
public:
RecodingTimeAfterBackForwardCacheRestoreFrameCallback(
PaintTiming* paint_timing,
size_t record_index)
: paint_timing_(paint_timing), record_index_(record_index) {}
~RecodingTimeAfterBackForwardCacheRestoreFrameCallback() override = default;
void Invoke(double high_res_time_ms) override {
// Instead of |high_res_time_ms|, use PaintTiming's |clock_->NowTicks()| for
// consistency and testability.
paint_timing_->SetRequestAnimationFrameAfterBackForwardCacheRestore(
record_index_, count_);
count_++;
if (count_ ==
WebPerformance::
kRequestAnimationFramesToRecordAfterBackForwardCacheRestore) {
paint_timing_->NotifyPaintTimingChanged();
return;
}
if (auto* frame = paint_timing_->GetFrame()) {
if (auto* document = frame->GetDocument()) {
document->RequestAnimationFrame(this);
}
}
}
void Trace(Visitor* visitor) const override {
visitor->Trace(paint_timing_);
FrameCallback::Trace(visitor);
}
private:
Member<PaintTiming> paint_timing_;
const size_t record_index_;
size_t count_ = 0;
};
// static // static
const char PaintTiming::kSupplementName[] = "PaintTiming"; const char PaintTiming::kSupplementName[] = "PaintTiming";
...@@ -334,6 +376,21 @@ void PaintTiming::SetFirstPaintAfterBackForwardCacheRestoreSwap( ...@@ -334,6 +376,21 @@ void PaintTiming::SetFirstPaintAfterBackForwardCacheRestoreSwap(
NotifyPaintTimingChanged(); NotifyPaintTimingChanged();
} }
void PaintTiming::SetRequestAnimationFrameAfterBackForwardCacheRestore(
size_t index,
size_t count) {
auto now = clock_->NowTicks();
// The elements are allocated when the page is restored from the cache.
DCHECK_LT(index,
request_animation_frames_after_back_forward_cache_restore_.size());
auto& current_rafs =
request_animation_frames_after_back_forward_cache_restore_[index];
DCHECK_LT(count, current_rafs.size());
DCHECK_EQ(current_rafs[count], base::TimeTicks());
current_rafs[count] = now;
}
void PaintTiming::ReportSwapResultHistogram(WebSwapResult result) { void PaintTiming::ReportSwapResultHistogram(WebSwapResult result) {
UMA_HISTOGRAM_ENUMERATION("PageLoad.Internal.Renderer.PaintTiming.SwapResult", UMA_HISTOGRAM_ENUMERATION("PageLoad.Internal.Renderer.PaintTiming.SwapResult",
result); result);
...@@ -343,9 +400,36 @@ void PaintTiming::OnRestoredFromBackForwardCache() { ...@@ -343,9 +400,36 @@ void PaintTiming::OnRestoredFromBackForwardCache() {
// Allocate the last element with 0, which indicates that the first paint // Allocate the last element with 0, which indicates that the first paint
// after this navigation doesn't happen yet. // after this navigation doesn't happen yet.
size_t index = first_paints_after_back_forward_cache_restore_swap_.size(); size_t index = first_paints_after_back_forward_cache_restore_swap_.size();
DCHECK_EQ(index,
request_animation_frames_after_back_forward_cache_restore_.size());
first_paints_after_back_forward_cache_restore_swap_.push_back( first_paints_after_back_forward_cache_restore_swap_.push_back(
base::TimeTicks()); base::TimeTicks());
RegisterNotifyFirstPaintAfterBackForwardCacheRestoreSwapTime(index); RegisterNotifyFirstPaintAfterBackForwardCacheRestoreSwapTime(index);
request_animation_frames_after_back_forward_cache_restore_.push_back(
RequestAnimationFrameTimesAfterBackForwardCacheRestore{});
LocalFrame* frame = GetFrame();
if (!frame->IsMainFrame()) {
return;
}
Document* document = frame->GetDocument();
DCHECK(document);
// Cancel if there is already a registered callback.
if (raf_after_bfcache_restore_measurement_callback_id_) {
document->CancelAnimationFrame(
raf_after_bfcache_restore_measurement_callback_id_);
raf_after_bfcache_restore_measurement_callback_id_ = 0;
}
raf_after_bfcache_restore_measurement_callback_id_ =
document->RequestAnimationFrame(
MakeGarbageCollected<
RecodingTimeAfterBackForwardCacheRestoreFrameCallback>(this,
index));
} }
} // namespace blink } // namespace blink
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "third_party/blink/public/web/web_performance.h"
#include "third_party/blink/public/web/web_swap_result.h" #include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h" #include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
...@@ -30,6 +31,10 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>, ...@@ -30,6 +31,10 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
friend class FirstMeaningfulPaintDetector; friend class FirstMeaningfulPaintDetector;
using ReportTimeCallback = using ReportTimeCallback =
WTF::CrossThreadOnceFunction<void(WebSwapResult, base::TimeTicks)>; WTF::CrossThreadOnceFunction<void(WebSwapResult, base::TimeTicks)>;
using RequestAnimationFrameTimesAfterBackForwardCacheRestore = std::array<
base::TimeTicks,
WebPerformance::
kRequestAnimationFramesToRecordAfterBackForwardCacheRestore>;
public: public:
static const char kSupplementName[]; static const char kSupplementName[];
...@@ -90,6 +95,11 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>, ...@@ -90,6 +95,11 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
return first_paints_after_back_forward_cache_restore_swap_; return first_paints_after_back_forward_cache_restore_swap_;
} }
WTF::Vector<RequestAnimationFrameTimesAfterBackForwardCacheRestore>
RequestAnimationFramesAfterBackForwardCacheRestore() const {
return request_animation_frames_after_back_forward_cache_restore_;
}
// FirstContentfulPaint returns the first time that 'contentful' content was // FirstContentfulPaint returns the first time that 'contentful' content was
// painted. For instance, the first time that text or image content was // painted. For instance, the first time that text or image content was
// painted. // painted.
...@@ -146,6 +156,8 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>, ...@@ -146,6 +156,8 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
void Trace(Visitor*) const override; void Trace(Visitor*) const override;
private: private:
friend class RecodingTimeAfterBackForwardCacheRestoreFrameCallback;
LocalFrame* GetFrame() const; LocalFrame* GetFrame() const;
void NotifyPaintTimingChanged(); void NotifyPaintTimingChanged();
...@@ -175,6 +187,8 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>, ...@@ -175,6 +187,8 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
// index to avoid confusing the data from different navigations. // index to avoid confusing the data from different navigations.
void SetFirstPaintAfterBackForwardCacheRestoreSwap(base::TimeTicks stamp, void SetFirstPaintAfterBackForwardCacheRestoreSwap(base::TimeTicks stamp,
size_t index); size_t index);
void SetRequestAnimationFrameAfterBackForwardCacheRestore(size_t index,
size_t count);
void RegisterNotifySwapTime(PaintEvent); void RegisterNotifySwapTime(PaintEvent);
void RegisterNotifyFirstPaintAfterBackForwardCacheRestoreSwapTime( void RegisterNotifyFirstPaintAfterBackForwardCacheRestoreSwapTime(
...@@ -193,6 +207,8 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>, ...@@ -193,6 +207,8 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
base::TimeTicks first_paint_swap_; base::TimeTicks first_paint_swap_;
WTF::Vector<base::TimeTicks> WTF::Vector<base::TimeTicks>
first_paints_after_back_forward_cache_restore_swap_; first_paints_after_back_forward_cache_restore_swap_;
WTF::Vector<RequestAnimationFrameTimesAfterBackForwardCacheRestore>
request_animation_frames_after_back_forward_cache_restore_;
base::TimeTicks first_image_paint_; base::TimeTicks first_image_paint_;
base::TimeTicks first_image_paint_swap_; base::TimeTicks first_image_paint_swap_;
base::TimeTicks first_contentful_paint_; base::TimeTicks first_contentful_paint_;
...@@ -205,6 +221,10 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>, ...@@ -205,6 +221,10 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
Member<FirstMeaningfulPaintDetector> fmp_detector_; Member<FirstMeaningfulPaintDetector> fmp_detector_;
// The callback ID for requestAnimationFrame to record its time after the page
// is restored from the back-forward cache.
int raf_after_bfcache_restore_measurement_callback_id_ = 0;
const base::TickClock* clock_; const base::TickClock* clock_;
FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, NoFirstPaint); FRIEND_TEST_ALL_PREFIXES(FirstMeaningfulPaintDetectorTest, NoFirstPaint);
......
...@@ -337,9 +337,16 @@ PerformanceTiming::BackForwardCacheRestore() const { ...@@ -337,9 +337,16 @@ PerformanceTiming::BackForwardCacheRestore() const {
load_timing->BackForwardCacheRestoreNavigationStarts(); load_timing->BackForwardCacheRestoreNavigationStarts();
WTF::Vector<base::TimeTicks> first_paints = WTF::Vector<base::TimeTicks> first_paints =
paint_timing->FirstPaintsAfterBackForwardCacheRestore(); paint_timing->FirstPaintsAfterBackForwardCacheRestore();
WTF::Vector<std::array<
base::TimeTicks,
WebPerformance::
kRequestAnimationFramesToRecordAfterBackForwardCacheRestore>>
request_animation_frames =
paint_timing->RequestAnimationFramesAfterBackForwardCacheRestore();
WTF::Vector<base::Optional<base::TimeDelta>> first_input_delays = WTF::Vector<base::Optional<base::TimeDelta>> first_input_delays =
interactive_detector->GetFirstInputDelaysAfterBackForwardCacheRestore(); interactive_detector->GetFirstInputDelaysAfterBackForwardCacheRestore();
DCHECK_EQ(navigation_starts.size(), first_paints.size()); DCHECK_EQ(navigation_starts.size(), first_paints.size());
DCHECK_EQ(navigation_starts.size(), request_animation_frames.size());
DCHECK_EQ(navigation_starts.size(), first_input_delays.size()); DCHECK_EQ(navigation_starts.size(), first_input_delays.size());
WTF::Vector<BackForwardCacheRestoreTiming> restore_timings( WTF::Vector<BackForwardCacheRestoreTiming> restore_timings(
...@@ -349,6 +356,10 @@ PerformanceTiming::BackForwardCacheRestore() const { ...@@ -349,6 +356,10 @@ PerformanceTiming::BackForwardCacheRestore() const {
MonotonicTimeToIntegerMilliseconds(navigation_starts[i]); MonotonicTimeToIntegerMilliseconds(navigation_starts[i]);
restore_timings[i].first_paint = restore_timings[i].first_paint =
MonotonicTimeToIntegerMilliseconds(first_paints[i]); MonotonicTimeToIntegerMilliseconds(first_paints[i]);
for (size_t j = 0; j < request_animation_frames[i].size(); j++) {
restore_timings[i].request_animation_frames[j] =
MonotonicTimeToIntegerMilliseconds(request_animation_frames[i][j]);
}
restore_timings[i].first_input_delay = first_input_delays[i]; restore_timings[i].first_input_delay = first_input_delays[i];
} }
return restore_timings; return restore_timings;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_TIMING_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_TIMING_H_
#include "base/time/time.h" #include "base/time/time.h"
#include "third_party/blink/public/web/web_performance.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
...@@ -61,6 +62,10 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable, ...@@ -61,6 +62,10 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
struct BackForwardCacheRestoreTiming { struct BackForwardCacheRestoreTiming {
uint64_t navigation_start; uint64_t navigation_start;
uint64_t first_paint; uint64_t first_paint;
std::array<uint64_t,
WebPerformance::
kRequestAnimationFramesToRecordAfterBackForwardCacheRestore>
request_animation_frames;
base::Optional<base::TimeDelta> first_input_delay; base::Optional<base::TimeDelta> first_input_delay;
}; };
......
...@@ -1990,6 +1990,23 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -1990,6 +1990,23 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary> </summary>
</histogram> </histogram>
<histogram
name="PageLoad.PaintTiming.NavigationToFirstPaint.BFCachePolyfill{Count}"
units="ms" expires_after="2021-11-01">
<owner>altimin@chromium.org</owner>
<owner>bmcquade@chromium.org</owner>
<owner>hajimehoshi@chromium.org</owner>
<summary>
Meastures the time duration between the page restore from BFcache and the
{Count} requestAnimationFrame time.
</summary>
<token key="Count">
<variant name="First"/>
<variant name="Second"/>
<variant name="Third"/>
</token>
</histogram>
<histogram name="PageLoad.PaintTiming.NavigationToLargestContentfulPaint" <histogram name="PageLoad.PaintTiming.NavigationToLargestContentfulPaint"
units="ms" expires_after="2021-04-04"> units="ms" expires_after="2021-04-04">
<owner>maxlg@chromium.org</owner> <owner>maxlg@chromium.org</owner>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment