mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1692350 - Implement a telemetry probe to collect page load data for documents that use lazyload r=emilio,chutten
Differential Revision: https://phabricator.services.mozilla.com/D104912
This commit is contained in:
parent
973901dc46
commit
93ae22d5b9
@ -5776,6 +5776,15 @@ var TabsProgressListener = {
|
||||
stopwatchRunning /* we won't see STATE_START events for pre-rendered tabs */
|
||||
) {
|
||||
if (recordLoadTelemetry) {
|
||||
if (aBrowser.browsingContext?.topWindowContext?.hadLazyLoadImage) {
|
||||
let timeElapsed = TelemetryStopwatch.timeElapsed(
|
||||
histogram,
|
||||
aBrowser
|
||||
);
|
||||
Services.telemetry
|
||||
.getHistogramById("FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS")
|
||||
.add(timeElapsed);
|
||||
}
|
||||
TelemetryStopwatch.finish(histogram, aBrowser);
|
||||
BrowserTelemetryUtils.recordSiteOriginTelemetry(browserWindows());
|
||||
}
|
||||
|
@ -260,6 +260,11 @@ bool WindowContext::CanSet(FieldIndex<IDX_IsLocalIP>, const bool& aValue,
|
||||
return CheckOnlyOwningProcessCanSet(aSource);
|
||||
}
|
||||
|
||||
bool WindowContext::CanSet(FieldIndex<IDX_HadLazyLoadImage>, const bool& aValue,
|
||||
ContentParent* aSource) {
|
||||
return IsTop();
|
||||
}
|
||||
|
||||
void WindowContext::DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>,
|
||||
bool aOldValue) {
|
||||
MOZ_ASSERT(
|
||||
|
@ -82,7 +82,10 @@ class BrowsingContextGroup;
|
||||
FIELD(HasReportedShadowDOMUsage, bool) \
|
||||
/* Whether the principal of this window is for a local \
|
||||
* IP address */ \
|
||||
FIELD(IsLocalIP, bool)
|
||||
FIELD(IsLocalIP, bool) \
|
||||
/* Whether the corresponding document has `loading='lazy'` \
|
||||
* images; It won't become false if the image becomes non-lazy */ \
|
||||
FIELD(HadLazyLoadImage, bool)
|
||||
|
||||
class WindowContext : public nsISupports, public nsWrapperCache {
|
||||
MOZ_DECL_SYNCED_CONTEXT(WindowContext, MOZ_EACH_WC_FIELD)
|
||||
@ -175,6 +178,8 @@ class WindowContext : public nsISupports, public nsWrapperCache {
|
||||
|
||||
bool CanShowPopup();
|
||||
|
||||
bool HadLazyLoadImage() const { return GetHadLazyLoadImage(); }
|
||||
|
||||
protected:
|
||||
WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
|
||||
uint64_t aOuterWindowId, bool aInProcess,
|
||||
@ -262,6 +267,9 @@ class WindowContext : public nsISupports, public nsWrapperCache {
|
||||
bool CanSet(FieldIndex<IDX_IsLocalIP>, const bool& aValue,
|
||||
ContentParent* aSource);
|
||||
|
||||
bool CanSet(FieldIndex<IDX_HadLazyLoadImage>, const bool& aValue,
|
||||
ContentParent* aSource);
|
||||
|
||||
void DidSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, bool aOldValue);
|
||||
|
||||
void DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>, bool aOldValue);
|
||||
|
@ -15572,6 +15572,17 @@ bool Document::ConsumeTransientUserGestureActivation() {
|
||||
return wc && wc->ConsumeTransientUserGestureActivation();
|
||||
}
|
||||
|
||||
void Document::IncLazyLoadImageCount() {
|
||||
if (!mLazyLoadImageCount) {
|
||||
if (WindowContext* wc = GetTopLevelWindowContext()) {
|
||||
if (!wc->HadLazyLoadImage()) {
|
||||
MOZ_ALWAYS_SUCCEEDS(wc->SetHadLazyLoadImage(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
++mLazyLoadImageCount;
|
||||
}
|
||||
|
||||
void Document::SetDocTreeHadMedia() {
|
||||
RefPtr<WindowContext> topWc = GetTopLevelWindowContext();
|
||||
if (topWc && !topWc->IsDiscarded() && !topWc->GetDocTreeHadMedia()) {
|
||||
|
@ -3739,7 +3739,7 @@ class Document : public nsINode,
|
||||
}
|
||||
DOMIntersectionObserver& EnsureLazyLoadImageObserver();
|
||||
DOMIntersectionObserver& EnsureLazyLoadImageObserverViewport();
|
||||
void IncLazyLoadImageCount() { ++mLazyLoadImageCount; }
|
||||
void IncLazyLoadImageCount();
|
||||
void DecLazyLoadImageCount() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mLazyLoadImageCount > 0);
|
||||
--mLazyLoadImageCount;
|
||||
|
@ -25,6 +25,10 @@ interface WindowContext {
|
||||
|
||||
// True if the principal of this window is for a local ip address.
|
||||
readonly attribute boolean isLocalIP;
|
||||
|
||||
// True if the corresponding document has `loading='lazy'` images;
|
||||
// It won't become false if the image becomes non-lazy.
|
||||
readonly attribute boolean hadLazyLoadImage;
|
||||
};
|
||||
|
||||
// Keep this in sync with nsIContentViewer::PermitUnloadAction.
|
||||
|
@ -26,3 +26,7 @@ support-files =
|
||||
support-files =
|
||||
file_lazyload_telemetry.html
|
||||
image_rgrg-256x256.png
|
||||
[browser_lazyload_page_load_telemetry_iframe.js]
|
||||
support-files =
|
||||
file_lazyload_telemetry.html
|
||||
image_rgrg-256x256.png
|
||||
|
@ -0,0 +1,48 @@
|
||||
const baseURL = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"http://example.com"
|
||||
);
|
||||
|
||||
const testFileURL = `${baseURL}file_lazyload_telemetry.html`;
|
||||
|
||||
const { TelemetryTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TelemetryTestUtils.jsm"
|
||||
);
|
||||
|
||||
function OtherLazyLoadDataIsReported() {
|
||||
const snapshot = Services.telemetry.getSnapshotForHistograms("main", false)
|
||||
.content;
|
||||
return snapshot.LAZYLOAD_IMAGE_TOTAL;
|
||||
}
|
||||
|
||||
function pageLoadIsReported() {
|
||||
const snapshot = Services.telemetry.getSnapshotForHistograms("main", false)
|
||||
.parent;
|
||||
return snapshot.FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS;
|
||||
}
|
||||
|
||||
add_task(async function testTelemetryCollection() {
|
||||
Services.telemetry.getHistogramById("FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS").clear();
|
||||
|
||||
const testTab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"data:text/html,<body><iframe src='" + testFileURL + "'></iframe></body>",
|
||||
true
|
||||
);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(pageLoadIsReported);
|
||||
|
||||
gBrowser.removeTab(testTab);
|
||||
|
||||
// Running this test also causes some other LAZYLOAD related data
|
||||
// to be collected. Wait for them to be collected to avoid firing
|
||||
// them at an unexpected time.
|
||||
await BrowserTestUtils.waitForCondition(OtherLazyLoadDataIsReported);
|
||||
|
||||
const snapshot = Services.telemetry.getSnapshotForHistograms("main", false);
|
||||
|
||||
ok(
|
||||
snapshot.parent.FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS.sum > 0,
|
||||
"lazyload image page load telemetry"
|
||||
);
|
||||
});
|
@ -9,6 +9,12 @@ const { TelemetryTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TelemetryTestUtils.jsm"
|
||||
);
|
||||
|
||||
function pageLoadIsReported() {
|
||||
const snapshot = Services.telemetry.getSnapshotForHistograms("main", false)
|
||||
.parent;
|
||||
return snapshot.FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS;
|
||||
}
|
||||
|
||||
function dataIsReported() {
|
||||
const snapshot = Services.telemetry.getSnapshotForHistograms("main", false)
|
||||
.content;
|
||||
@ -25,6 +31,7 @@ add_task(async function testTelemetryCollection() {
|
||||
.getHistogramById("LAZYLOAD_IMAGE_VIEWPORT_LOADING")
|
||||
.clear();
|
||||
Services.telemetry.getHistogramById("LAZYLOAD_IMAGE_VIEWPORT_LOADED").clear();
|
||||
Services.telemetry.getHistogramById("FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS").clear();
|
||||
|
||||
const testTab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
@ -47,20 +54,21 @@ add_task(async function testTelemetryCollection() {
|
||||
}
|
||||
);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(pageLoadIsReported);
|
||||
|
||||
gBrowser.removeTab(testTab);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(dataIsReported);
|
||||
|
||||
const snapshot = Services.telemetry.getSnapshotForHistograms("main", false)
|
||||
.content;
|
||||
const snapshot = Services.telemetry.getSnapshotForHistograms("main", false);
|
||||
|
||||
// Ensures we have 4 lazyload images.
|
||||
is(snapshot.LAZYLOAD_IMAGE_TOTAL.values[4], 1, "total images");
|
||||
is(snapshot.content.LAZYLOAD_IMAGE_TOTAL.values[4], 1, "total images");
|
||||
// All 4 images should be lazy-loaded.
|
||||
is(snapshot.LAZYLOAD_IMAGE_STARTED.values[4], 1, "started to load");
|
||||
is(snapshot.content.LAZYLOAD_IMAGE_STARTED.values[4], 1, "started to load");
|
||||
// The last image didn't reach to the viewport.
|
||||
is(
|
||||
snapshot.LAZYLOAD_IMAGE_NOT_VIEWPORT.values[1],
|
||||
snapshot.content.LAZYLOAD_IMAGE_NOT_VIEWPORT.values[1],
|
||||
1,
|
||||
"images didn't reach viewport"
|
||||
);
|
||||
@ -68,9 +76,13 @@ add_task(async function testTelemetryCollection() {
|
||||
// should be three. This includes all images except
|
||||
// the last one.
|
||||
is(
|
||||
snapshot.LAZYLOAD_IMAGE_VIEWPORT_LOADING.sum +
|
||||
snapshot.LAZYLOAD_IMAGE_VIEWPORT_LOADED.sum,
|
||||
snapshot.content.LAZYLOAD_IMAGE_VIEWPORT_LOADING.sum +
|
||||
snapshot.content.LAZYLOAD_IMAGE_VIEWPORT_LOADED.sum,
|
||||
3,
|
||||
"images reached viewport"
|
||||
);
|
||||
ok(
|
||||
snapshot.parent.FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS.sum > 0,
|
||||
"lazyload image page load telemetry"
|
||||
);
|
||||
});
|
||||
|
@ -7708,6 +7708,18 @@
|
||||
"alert_emails": ["tdsmith@mozilla.com", "perf-telemetry-alerts@mozilla.com", "product-metrics-telemetry-alerts@mozilla.com"],
|
||||
"releaseChannelCollection": "opt-out"
|
||||
},
|
||||
"FX_LAZYLOAD_IMAGE_PAGE_LOAD_MS": {
|
||||
"record_in_processes": ["main"],
|
||||
"products": ["firefox"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "linear",
|
||||
"high": 10000,
|
||||
"n_buckets": 100,
|
||||
"description": "Firefox: Time taken to load a page that has at least one `loading='lazy'` image. (This metric includes both loads and reloads)",
|
||||
"bug_numbers": [1692350],
|
||||
"alert_emails": ["sefeng@mozilla.com", "perf-telemetry-alerts@mozilla.com"],
|
||||
"releaseChannelCollection": "opt-out"
|
||||
},
|
||||
"FX_PAGE_RELOAD_NORMAL_MS": {
|
||||
"record_in_processes": ["main"],
|
||||
"products": ["firefox", "fennec"],
|
||||
|
Loading…
Reference in New Issue
Block a user