Commit df88f2bf authored by Scott Little's avatar Scott Little Committed by Commit Bot

LazyLoad: Record VisibleLoadTime metrics after the image becomes visible

Before this CL, the VisibleLoadTime metrics for image elements are
recorded when the image finishes loading. This means that:

(a) Images that finish loading before the image element's visibility
observer triggers for the first time will have their VisibleLoadTime
recorded as being below-the-fold, even if the image is actually
above-the-fold,

(b) When automatic lazyloading is disabled, VisibleLoadTime samples will
be recorded for images that finish loading even if the viewport is never
scrolled near the image, meaning that many more samples will be recorded
than when automatic lazyloading is enabled.

To solve this, this CL changes VisibleLoadTime for images to be recorded
after the image becomes visible, instead of being recorded when the
image finishes loading. This also makes the metric consistent with how
VisibleLoadTime is recorded for frames.

Bug: 1010761
Change-Id: I2d89d413df1d49a2aa0d8974fcc188d86e0e6d92
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1870109Reviewed-by: default avatarrajendrant <rajendrant@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Commit-Queue: Scott Little <sclittle@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708267}
parent 1b984c2b
...@@ -32,11 +32,11 @@ class LazyLoadImageObserver final ...@@ -32,11 +32,11 @@ class LazyLoadImageObserver final
bool is_initially_intersecting = false; bool is_initially_intersecting = false;
bool has_initial_intersection_been_set = false; bool has_initial_intersection_been_set = false;
// True if metrics need to be recorded and has not been recorded yet.
bool record_visibility_metrics = false;
// Set when the image first becomes visible (i.e. appears in the viewport). // Set when the image first becomes visible (i.e. appears in the viewport).
base::TimeTicks time_when_first_visible; base::TimeTicks time_when_first_visible;
// Set when the first load event is dispatched for the image.
base::TimeTicks time_when_first_load_finished;
}; };
LazyLoadImageObserver(const Document&); LazyLoadImageObserver(const Document&);
......
...@@ -1451,6 +1451,202 @@ TEST_F(LazyLoadAutomaticImagesTest, LazyLoadDisabledOnReload) { ...@@ -1451,6 +1451,202 @@ TEST_F(LazyLoadAutomaticImagesTest, LazyLoadDisabledOnReload) {
} }
} }
TEST_F(LazyLoadAutomaticImagesTest, AboveTheFoldImageLoadedBeforeVisible) {
ScopedLazyImageLoadingMetadataFetchForTest
scoped_lazy_image_loading_metadata_fetch_for_test = false;
HistogramTester histogram_tester;
// Since the image is above the fold, ensure that the image starts loading
// before it becomes visible. When automatic lazyloading is enabled, the main
// way that an above-the-fold image that's relevant to automatic lazyload
// (i.e. would have visible load time metrics recorded for it) can be finshed
// loading by the time it becomes visible is for it to be fully loaded as one
// of the first K images seen by the parser.
SetLazyImageFirstKFullyLoad(1);
SimRequest main_resource("https://example.com/", "text/html");
SimSubresourceRequest image_resource("https://example.com/image.png",
"image/png");
LoadURL("https://example.com/");
main_resource.Complete(
"<body><img src='https://example.com/image.png' /></body>");
image_resource.Complete(ReadTestImage());
// VisibleLoadTime should not have been recorded yet, since the image is not
// visible yet.
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.4G", 0);
Compositor().BeginFrame();
test::RunPendingTasks();
histogram_tester.ExpectTotalCount(
"Blink.VisibleBeforeLoaded.LazyLoadImages.AboveTheFold", 0);
histogram_tester.ExpectTotalCount(
"Blink.VisibleBeforeLoaded.LazyLoadImages.BelowTheFold", 0);
histogram_tester.ExpectUniqueSample(
"Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.4G", 0, 1);
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.4G", 0);
}
TEST_F(LazyLoadAutomaticImagesTest, AboveTheFoldImageVisibleBeforeLoaded) {
ScopedLazyImageLoadingMetadataFetchForTest
scoped_lazy_image_loading_metadata_fetch_for_test = false;
HistogramTester histogram_tester;
SimRequest main_resource("https://example.com/", "text/html");
SimSubresourceRequest image_resource("https://example.com/image.png",
"image/png");
LoadURL("https://example.com/");
main_resource.Complete(
"<body><img src='https://example.com/image.png' /></body>");
Compositor().BeginFrame();
test::RunPendingTasks();
// VisibleBeforeLoaded should have been recorded immediately when the image
// became visible.
histogram_tester.ExpectUniqueSample(
"Blink.VisibleBeforeLoaded.LazyLoadImages.AboveTheFold",
static_cast<int>(WebEffectiveConnectionType::kType4G), 1);
// VisibleLoadTime should not have been recorded yet, since the image is not
// finished loading yet.
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.4G", 0);
image_resource.Complete(ReadTestImage());
Compositor().BeginFrame();
test::RunPendingTasks();
histogram_tester.ExpectUniqueSample(
"Blink.VisibleBeforeLoaded.LazyLoadImages.AboveTheFold",
static_cast<int>(WebEffectiveConnectionType::kType4G), 1);
histogram_tester.ExpectTotalCount(
"Blink.VisibleBeforeLoaded.LazyLoadImages.BelowTheFold", 0);
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.4G", 1);
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.4G", 0);
}
TEST_F(LazyLoadAutomaticImagesTest, BelowTheFoldImageLoadedBeforeVisible) {
ScopedLazyImageLoadingMetadataFetchForTest
scoped_lazy_image_loading_metadata_fetch_for_test = false;
HistogramTester histogram_tester;
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete(String::Format(
R"HTML(
<body>
<div style='height: %dpx;'></div>
<img src='https://example.com/image.png' />
</body>)HTML",
kViewportHeight + kLoadingDistanceThreshold + 100));
Compositor().BeginFrame();
test::RunPendingTasks();
SimSubresourceRequest image_resource("https://example.com/image.png",
"image/png");
// Scroll down such that the image is within kLoadingDistanceThreshold of the
// viewport, but isn't visible yet.
GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 200),
kProgrammaticScroll);
Compositor().BeginFrame();
test::RunPendingTasks();
image_resource.Complete(ReadTestImage());
Compositor().BeginFrame();
test::RunPendingTasks();
// VisibleLoadTime should not have been recorded yet, since the image is not
// visible yet.
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.4G", 0);
// Scroll down such that the image is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, kViewportHeight + kLoadingDistanceThreshold),
kProgrammaticScroll);
Compositor().BeginFrame();
test::RunPendingTasks();
histogram_tester.ExpectTotalCount(
"Blink.VisibleBeforeLoaded.LazyLoadImages.AboveTheFold", 0);
histogram_tester.ExpectTotalCount(
"Blink.VisibleBeforeLoaded.LazyLoadImages.BelowTheFold", 0);
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.4G", 0);
histogram_tester.ExpectUniqueSample(
"Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.4G", 0, 1);
}
TEST_F(LazyLoadAutomaticImagesTest, BelowTheFoldImageVisibleBeforeLoaded) {
ScopedLazyImageLoadingMetadataFetchForTest
scoped_lazy_image_loading_metadata_fetch_for_test = false;
HistogramTester histogram_tester;
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete(String::Format(
R"HTML(
<body>
<div style='height: %dpx;'></div>
<img src='https://example.com/image.png' />
</body>)HTML",
kViewportHeight + kLoadingDistanceThreshold + 100));
Compositor().BeginFrame();
test::RunPendingTasks();
SimSubresourceRequest image_resource("https://example.com/image.png",
"image/png");
// Scroll down such that the image is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, kViewportHeight + kLoadingDistanceThreshold),
kProgrammaticScroll);
Compositor().BeginFrame();
test::RunPendingTasks();
// VisibleBeforeLoaded should have been recorded immediately when the image
// became visible.
histogram_tester.ExpectUniqueSample(
"Blink.VisibleBeforeLoaded.LazyLoadImages.BelowTheFold",
static_cast<int>(WebEffectiveConnectionType::kType4G), 1);
// VisibleLoadTime should not have been recorded yet, since the image is not
// finished loading yet.
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.4G", 0);
image_resource.Complete(ReadTestImage());
Compositor().BeginFrame();
test::RunPendingTasks();
histogram_tester.ExpectTotalCount(
"Blink.VisibleBeforeLoaded.LazyLoadImages.AboveTheFold", 0);
histogram_tester.ExpectUniqueSample(
"Blink.VisibleBeforeLoaded.LazyLoadImages.BelowTheFold",
static_cast<int>(WebEffectiveConnectionType::kType4G), 1);
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.4G", 0);
histogram_tester.ExpectTotalCount(
"Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.4G", 1);
}
} // namespace } // namespace
} // namespace blink } // namespace blink
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