From 712dda078ca5d0b76bf7b98d50ceaaa27000b24f Mon Sep 17 00:00:00 2001 From: Sean Feng Date: Tue, 30 Aug 2022 16:00:11 +0000 Subject: [PATCH] Bug 1750034 - Remove lazyload telemetry related code r=emilio We have decided to use 600px in all directions, there's no need to keep the telemetry stuff around. Differential Revision: https://phabricator.services.mozilla.com/D155879 --- browser/base/content/browser.js | 9 -- docshell/base/WindowContext.cpp | 5 -- docshell/base/WindowContext.h | 8 -- dom/base/DOMIntersectionObserver.cpp | 22 +---- dom/base/Document.cpp | 50 ----------- dom/base/Document.h | 21 ----- dom/chrome-webidl/WindowGlobalActors.webidl | 4 - dom/html/HTMLImageElement.cpp | 28 +----- dom/html/HTMLImageElement.h | 4 +- layout/base/tests/browser.ini | 8 -- ...ser_lazyload_page_load_telemetry_iframe.js | 48 ---------- .../base/tests/browser_lazyload_telemetry.js | 88 ------------------- toolkit/components/telemetry/Histograms.json | 72 --------------- 13 files changed, 5 insertions(+), 362 deletions(-) delete mode 100644 layout/base/tests/browser_lazyload_page_load_telemetry_iframe.js delete mode 100644 layout/base/tests/browser_lazyload_telemetry.js diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 446825d105d9..4b9a0426bc82 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6066,15 +6066,6 @@ 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()); } diff --git a/docshell/base/WindowContext.cpp b/docshell/base/WindowContext.cpp index a6448f59f8e6..4cff17fe9236 100644 --- a/docshell/base/WindowContext.cpp +++ b/docshell/base/WindowContext.cpp @@ -284,11 +284,6 @@ bool WindowContext::CanSet(FieldIndex, const bool& aValue, return CheckOnlyOwningProcessCanSet(aSource); } -bool WindowContext::CanSet(FieldIndex, const bool& aValue, - ContentParent* aSource) { - return IsTop(); -} - bool WindowContext::CanSet(FieldIndex, bool aValue, ContentParent* aSource) { return (XRE_IsParentProcess() && !aSource) || diff --git a/docshell/base/WindowContext.h b/docshell/base/WindowContext.h index 3b3c6430dbe9..f057352a9f3a 100644 --- a/docshell/base/WindowContext.h +++ b/docshell/base/WindowContext.h @@ -85,9 +85,6 @@ class BrowsingContextGroup; /* Whether the principal of this window is for a local \ * IP address */ \ 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) \ /* Whether any of the windows in the subtree rooted at this window has \ * active peer connections or not (only set on the top window). */ \ FIELD(HasActivePeerConnections, bool) \ @@ -205,8 +202,6 @@ class WindowContext : public nsISupports, public nsWrapperCache { bool CanShowPopup(); - bool HadLazyLoadImage() const { return GetHadLazyLoadImage(); } - bool AllowJavascript() const { return GetAllowJavascript(); } bool CanExecuteScripts() const { return mCanExecuteScripts; } @@ -302,9 +297,6 @@ class WindowContext : public nsISupports, public nsWrapperCache { bool CanSet(FieldIndex, const bool& aValue, ContentParent* aSource); - bool CanSet(FieldIndex, const bool& aValue, - ContentParent* aSource); - bool CanSet(FieldIndex, bool aValue, ContentParent* aSource); void DidSet(FieldIndex, bool aOldValue); diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp index ceec0634f5b9..7c766277834a 100644 --- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -145,19 +145,7 @@ static void LazyLoadCallback( MOZ_ASSERT(entry->Target()->IsHTMLElement(nsGkAtoms::img)); if (entry->IsIntersecting()) { static_cast(entry->Target()) - ->StopLazyLoading(HTMLImageElement::FromIntersectionObserver::Yes, - HTMLImageElement::StartLoading::Yes); - } - } -} - -static void LazyLoadCallbackReachViewport( - const Sequence>& aEntries) { - for (const auto& entry : aEntries) { - MOZ_ASSERT(entry->Target()->IsHTMLElement(nsGkAtoms::img)); - if (entry->IsIntersecting()) { - static_cast(entry->Target()) - ->LazyLoadImageReachedViewport(); + ->StopLazyLoading(HTMLImageElement::StartLoading::Yes); } } } @@ -194,14 +182,6 @@ DOMIntersectionObserver::CreateLazyLoadObserver(Document& aDocument) { return observer.forget(); } -already_AddRefed -DOMIntersectionObserver::CreateLazyLoadObserverViewport(Document& aDocument) { - RefPtr observer = - new DOMIntersectionObserver(aDocument, LazyLoadCallbackReachViewport); - observer->mThresholds.AppendElement(0.0f); - return observer.forget(); -} - bool DOMIntersectionObserver::SetRootMargin(const nsACString& aString) { return Servo_IntersectionObserverRootMargin_Parse(&aString, &mRootMargin); } diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 04e749d1b7a9..41c55a696777 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -1404,10 +1404,6 @@ Document::Document(const char* aContentType) mXMLDeclarationBits(0), mOnloadBlockCount(0), mWriteLevel(0), - mLazyLoadImageCount(0), - mLazyLoadImageStarted(0), - mLazyLoadImageReachViewportLoading(0), - mLazyLoadImageReachViewportLoaded(0), mContentEditableCount(0), mEditingState(EditingState::eOff), mCompatMode(eCompatibility_FullStandards), @@ -15617,25 +15613,6 @@ void Document::ReportDocumentUseCounters() { (" > %s\n", Telemetry::GetHistogramName(id))); Telemetry::Accumulate(id, 1); } - - ReportDocumentLazyLoadCounters(); -} - -void Document::ReportDocumentLazyLoadCounters() { - if (!mLazyLoadImageCount) { - return; - } - Telemetry::Accumulate(Telemetry::LAZYLOAD_IMAGE_TOTAL, mLazyLoadImageCount); - Telemetry::Accumulate(Telemetry::LAZYLOAD_IMAGE_STARTED, - mLazyLoadImageStarted); - Telemetry::Accumulate(Telemetry::LAZYLOAD_IMAGE_NOT_VIEWPORT, - mLazyLoadImageStarted - - mLazyLoadImageReachViewportLoading - - mLazyLoadImageReachViewportLoaded); - Telemetry::Accumulate(Telemetry::LAZYLOAD_IMAGE_VIEWPORT_LOADING, - mLazyLoadImageReachViewportLoading); - Telemetry::Accumulate(Telemetry::LAZYLOAD_IMAGE_VIEWPORT_LOADED, - mLazyLoadImageReachViewportLoaded); } void Document::SendPageUseCounters() { @@ -15752,22 +15729,6 @@ DOMIntersectionObserver& Document::EnsureLazyLoadImageObserver() { return *mLazyLoadImageObserver; } -DOMIntersectionObserver& Document::EnsureLazyLoadImageObserverViewport() { - if (!mLazyLoadImageObserverViewport) { - mLazyLoadImageObserverViewport = - DOMIntersectionObserver::CreateLazyLoadObserverViewport(*this); - } - return *mLazyLoadImageObserverViewport; -} - -void Document::IncLazyLoadImageReachViewport(bool aLoading) { - if (aLoading) { - ++mLazyLoadImageReachViewportLoading; - } else { - ++mLazyLoadImageReachViewportLoaded; - } -} - ResizeObserver& Document::EnsureLastRememberedSizeObserver() { if (!mLastRememberedSizeObserver) { mLastRememberedSizeObserver = @@ -16158,17 +16119,6 @@ bool Document::ConsumeTransientUserGestureActivation() { return wc && wc->ConsumeTransientUserGestureActivation(); } -void Document::IncLazyLoadImageCount() { - if (!mLazyLoadImageCount) { - if (WindowContext* wc = GetTopLevelWindowContext()) { - if (!wc->HadLazyLoadImage()) { - Unused << wc->SetHadLazyLoadImage(true); - } - } - } - ++mLazyLoadImageCount; -} - void Document::SetDocTreeHadMedia() { RefPtr topWc = GetTopLevelWindowContext(); if (topWc && !topWc->IsDiscarded() && !topWc->GetDocTreeHadMedia()) { diff --git a/dom/base/Document.h b/dom/base/Document.h index 16ec54182923..c491cd26bad5 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -3747,14 +3747,6 @@ class Document : public nsINode, return mLazyLoadImageObserverViewport; } DOMIntersectionObserver& EnsureLazyLoadImageObserver(); - DOMIntersectionObserver& EnsureLazyLoadImageObserverViewport(); - void IncLazyLoadImageCount(); - void DecLazyLoadImageCount() { - MOZ_DIAGNOSTIC_ASSERT(mLazyLoadImageCount > 0); - --mLazyLoadImageCount; - } - void IncLazyLoadImageStarted() { ++mLazyLoadImageStarted; } - void IncLazyLoadImageReachViewport(bool aLoading); ResizeObserver* GetLastRememberedSizeObserver() { return mLastRememberedSizeObserver; @@ -4833,19 +4825,6 @@ class Document : public nsINode, // finishes processing that script. uint32_t mWriteLevel; - // The amount of images that have `loading="lazy"` on the page or have loaded - // lazily already. - uint32_t mLazyLoadImageCount; - // Number of lazy-loaded images that we've started loading as a result of - // triggering the lazy-load observer threshold. - uint32_t mLazyLoadImageStarted; - // Number of lazy-loaded images that reached the viewport which were not done - // loading when they did so. - uint32_t mLazyLoadImageReachViewportLoading; - // Number of lazy-loaded images that reached the viewport and were done - // loading when they did so. - uint32_t mLazyLoadImageReachViewportLoaded; - uint32_t mContentEditableCount; EditingState mEditingState; diff --git a/dom/chrome-webidl/WindowGlobalActors.webidl b/dom/chrome-webidl/WindowGlobalActors.webidl index 49dc5bdde902..dd85d8a4d0da 100644 --- a/dom/chrome-webidl/WindowGlobalActors.webidl +++ b/dom/chrome-webidl/WindowGlobalActors.webidl @@ -33,10 +33,6 @@ 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; - /** * Partially determines whether script execution is allowed in this * BrowsingContext. Script execution will be permitted only if this diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp index 951c5e013dd6..ff694dd01824 100644 --- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -347,7 +347,7 @@ nsresult HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, SetLazyLoading(); } else if (aOldValue && Loading(aOldValue->GetEnumValue()) == Loading::Lazy) { - StopLazyLoading(FromIntersectionObserver::No, StartLoading::Yes); + StopLazyLoading(StartLoading::Yes); } } else if (aName == nsGkAtoms::src && !aValue) { // NOTE: regular src value changes are handled in AfterMaybeChangeAttr, so @@ -662,7 +662,6 @@ void HTMLImageElement::NodeInfoChanged(Document* aOldDoc) { if (mLazyLoading) { aOldDoc->GetLazyLoadImageObserver()->Unobserve(*this); - aOldDoc->DecLazyLoadImageCount(); mLazyLoading = false; SetLazyLoading(); } @@ -939,7 +938,7 @@ nsresult HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, triggeringPrincipal, GetCORSMode())) { return NS_OK; } - StopLazyLoading(FromIntersectionObserver::No, StartLoading::No); + StopLazyLoading(StartLoading::No); } nsresult rv = NS_ERROR_FAILURE; @@ -1298,8 +1297,6 @@ void HTMLImageElement::SetLazyLoading() { } doc->EnsureLazyLoadImageObserver().Observe(*this); - doc->EnsureLazyLoadImageObserverViewport().Observe(*this); - doc->IncLazyLoadImageCount(); mLazyLoading = true; UpdateImageState(true); } @@ -1320,9 +1317,7 @@ void HTMLImageElement::StartLoadingIfNeeded() { } } -void HTMLImageElement::StopLazyLoading( - FromIntersectionObserver aFromIntersectionObserver, - StartLoading aStartLoading) { +void HTMLImageElement::StopLazyLoading(StartLoading aStartLoading) { if (!mLazyLoading) { return; } @@ -1332,28 +1327,11 @@ void HTMLImageElement::StopLazyLoading( obs->Unobserve(*this); } - if (bool(aFromIntersectionObserver)) { - doc->IncLazyLoadImageStarted(); - } else { - doc->DecLazyLoadImageCount(); - if (auto* obs = doc->GetLazyLoadImageObserverViewport()) { - obs->Unobserve(*this); - } - } - if (bool(aStartLoading)) { StartLoadingIfNeeded(); } } -void HTMLImageElement::LazyLoadImageReachedViewport() { - Document* doc = OwnerDoc(); - if (auto* obs = doc->GetLazyLoadImageObserverViewport()) { - obs->Unobserve(*this); - } - doc->IncLazyLoadImageReachViewport(!Complete()); -} - const nsMappedAttributes* HTMLImageElement::GetMappedAttributesFromSource() const { if (!IsInPicture() || !mResponsiveSelector || diff --git a/dom/html/HTMLImageElement.h b/dom/html/HTMLImageElement.h index 525a7e904477..9c031e007c39 100644 --- a/dom/html/HTMLImageElement.h +++ b/dom/html/HTMLImageElement.h @@ -266,9 +266,7 @@ class HTMLImageElement final : public nsGenericHTMLElement, enum class FromIntersectionObserver : bool { No, Yes }; enum class StartLoading : bool { No, Yes }; - void StopLazyLoading(FromIntersectionObserver, StartLoading); - - void LazyLoadImageReachedViewport(); + void StopLazyLoading(StartLoading); // This is used when restyling, for retrieving the extra style from the source // element. diff --git a/layout/base/tests/browser.ini b/layout/base/tests/browser.ini index c3615fa77435..64c3874402b0 100644 --- a/layout/base/tests/browser.ini +++ b/layout/base/tests/browser.ini @@ -30,11 +30,3 @@ skip-if = support-files = !/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js !/browser/base/content/test/forms/head.js -[browser_lazyload_telemetry.js] -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 diff --git a/layout/base/tests/browser_lazyload_page_load_telemetry_iframe.js b/layout/base/tests/browser_lazyload_page_load_telemetry_iframe.js deleted file mode 100644 index b700a229d157..000000000000 --- a/layout/base/tests/browser_lazyload_page_load_telemetry_iframe.js +++ /dev/null @@ -1,48 +0,0 @@ -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,", - 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" - ); -}); diff --git a/layout/base/tests/browser_lazyload_telemetry.js b/layout/base/tests/browser_lazyload_telemetry.js deleted file mode 100644 index 745e2b513bd1..000000000000 --- a/layout/base/tests/browser_lazyload_telemetry.js +++ /dev/null @@ -1,88 +0,0 @@ -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 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; - return ( - snapshot.LAZYLOAD_IMAGE_STARTED && snapshot.LAZYLOAD_IMAGE_STARTED.values[4] - ); -} - -add_task(async function testTelemetryCollection() { - Services.telemetry.getHistogramById("LAZYLOAD_IMAGE_TOTAL").clear(); - Services.telemetry.getHistogramById("LAZYLOAD_IMAGE_STARTED").clear(); - Services.telemetry.getHistogramById("LAZYLOAD_IMAGE_NOT_VIEWPORT").clear(); - Services.telemetry - .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, - testFileURL, - true - ); - - await SpecialPowers.spawn( - testTab.linkedBrowser.browsingContext, - [], - async () => { - const image2 = content.document.getElementById("image2"); - image2.scrollIntoView(); - - await new Promise(resolve => { - content.requestAnimationFrame(() => { - content.requestAnimationFrame(resolve); - }); - }); - } - ); - - await BrowserTestUtils.waitForCondition(pageLoadIsReported); - - gBrowser.removeTab(testTab); - - await BrowserTestUtils.waitForCondition(dataIsReported); - - const snapshot = Services.telemetry.getSnapshotForHistograms("main", false); - - // Ensures we have 4 lazyload images. - is(snapshot.content.LAZYLOAD_IMAGE_TOTAL.values[4], 1, "total images"); - // All 4 images should be lazy-loaded. - is(snapshot.content.LAZYLOAD_IMAGE_STARTED.values[4], 1, "started to load"); - // The last image didn't reach to the viewport. - is( - snapshot.content.LAZYLOAD_IMAGE_NOT_VIEWPORT.values[1], - 1, - "images didn't reach viewport" - ); - // The sum of the images that reached to the viewport - // should be three. This includes all images except - // the last one. - is( - 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" - ); -}); diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 5bda546a99b8..dda8a0845a32 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -5479,66 +5479,6 @@ "releaseChannelCollection": "opt-out", "description": "How long (sec) a tab had been unloaded until it was reloaded." }, - "LAZYLOAD_IMAGE_TOTAL": { - "record_in_processes": ["main", "content"], - "products": ["firefox"], - "alert_emails": ["sefeng@mozilla.com"], - "bug_numbers": [1687358], - "expires_in_version": "never", - "kind": "exponential", - "high": 2000, - "n_buckets": 100, - "releaseChannelCollection": "opt-out", - "description": "The amount of images that have `loading='lazy'` on the page or have loaded lazily already." - }, - "LAZYLOAD_IMAGE_STARTED": { - "record_in_processes": ["main", "content"], - "products": ["firefox"], - "alert_emails": ["sefeng@mozilla.com"], - "bug_numbers": [1687358], - "expires_in_version": "never", - "kind": "exponential", - "high": 2000, - "n_buckets": 100, - "releaseChannelCollection": "opt-out", - "description": "Number of lazy-loaded images that we've started loading as a result of triggering the lazy-load observer threshold." - }, - "LAZYLOAD_IMAGE_NOT_VIEWPORT": { - "record_in_processes": ["main", "content"], - "products": ["firefox"], - "alert_emails": ["sefeng@mozilla.com"], - "bug_numbers": [1687358], - "expires_in_version": "never", - "kind": "exponential", - "high": 2000, - "n_buckets": 100, - "releaseChannelCollection": "opt-out", - "description": "Number of lazy-loaded images that were started to load but didn't reach to the viewport eventually" - }, - "LAZYLOAD_IMAGE_VIEWPORT_LOADING": { - "record_in_processes": ["main", "content"], - "products": ["firefox"], - "alert_emails": ["sefeng@mozilla.com"], - "bug_numbers": [1687358], - "expires_in_version": "never", - "kind": "exponential", - "high": 2000, - "n_buckets": 100, - "releaseChannelCollection": "opt-out", - "description": "Number of lazy-loaded images that reached the viewport which were not done loading when they did so." - }, - "LAZYLOAD_IMAGE_VIEWPORT_LOADED": { - "record_in_processes": ["main", "content"], - "products": ["firefox"], - "alert_emails": ["sefeng@mozilla.com"], - "bug_numbers": [1687358], - "expires_in_version": "never", - "kind": "exponential", - "high": 2000, - "n_buckets": 100, - "releaseChannelCollection": "opt-out", - "description": "Number of lazy-loaded images that reached the viewport and were done loading when they did so." - }, "LOADED_TAB_COUNT": { "record_in_processes": ["main"], "products": ["firefox"], @@ -8192,18 +8132,6 @@ "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"],