/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include"mozilla/dom/Element.h" #include"nsContentUtils.h" #include"nsLayoutUtils.h" #include"nsRFPService.h" #include"Performance.h" #include"imgRequest.h" #include"PerformanceMainThread.h" #include"LargestContentfulPaint.h"
if (!aContainingElement->ChromeOnlyAccess()) { returntrue;
}
// Exception: this is a poster image of video element if (nsIContent* parent = aContainingElement->GetParent()) {
nsVideoFrame* videoFrame = do_QueryFrame(parent->GetPrimaryFrame()); if (videoFrame && videoFrame->GetPosterImage() == aContainingElement) { returntrue;
}
}
// Exception: CSS generated images if (aContainingElement->IsInNativeAnonymousSubtree()) { if (nsINode* rootParentOrHost =
aContainingElement
->GetClosestNativeAnonymousSubtreeRootParentOrHost()) { if (!rootParentOrHost->ChromeOnlyAccess()) { returntrue;
}
}
} returnfalse;
} void LargestContentfulPaint::MaybeProcessImageForElementTiming(
imgRequestProxy* aRequest, Element* aElement) { if (!StaticPrefs::dom_enable_largest_contentful_paint()) { return;
}
if (imageRequestProxiesForElement.Contains(aRequest)) {
LOG(" The content identifier existed for element=%p and request=%p, " "return.",
aElement, aRequest); return;
}
// At this point, the loadTime of the image is known, but // the renderTime is unknown, so it's added to ImagesPendingRendering // as a placeholder, and the corresponding LCP entry will be created // when the renderTime is known. // Here we are exposing the load time of the image which could be // a privacy concern. The spec talks about it at // https://wicg.github.io/element-timing/#sec-security // TLDR: The similar metric can be obtained by ResourceTiming // API and onload handlers already, so this is not exposing anything // new.
LOG(" Added a pending image rendering");
performance->AddImagesPendingRendering(
ImagePendingRendering{aElement, aRequest, TimeStamp::Now()});
}
bool LCPHelpers::CanFinalizeLCPEntry(const nsIFrame* aFrame) { if (!StaticPrefs::dom_enable_largest_contentful_paint()) { returnfalse;
}
// Resets the LCPTiming so that unless this (element, image) pair goes // through PerformanceMainThread::ProcessElementTiming again, they // won't generate new LCP entries.
lcpTimings.Reset();
// If area is less than or equal to document’s largest contentful paint size, // return. if (!performance->UpdateLargestContentfulPaintSize(entry->Size())) {
LOG(
" This paint(%lu) is not greater than the largest paint (%lf)that " "we've " "reported so far, return",
entry->Size(), performance->GetLargestContentfulPaintSize()); return;
}
// Let visibleDimensions be concreteDimensions, adjusted for positioning // by object-position or background-position and element’s content box. const nsRect& visibleDimensions = aTargetRectRelativeToSelf;
// Let clientContentRect be the smallest DOMRectReadOnly containing // visibleDimensions with element’s transforms applied.
nsRect clientContentRect = nsLayoutUtils::TransformFrameRectToAncestor(
frame, visibleDimensions, rootFrame);
// Let intersectionRect be the value returned by the intersection rect // algorithm using element as the target and viewport as the root. // (From https://wicg.github.io/element-timing/#sec-report-image-element)
IntersectionInput input = DOMIntersectionObserver::ComputeInput(
*frame->PresContext()->Document(), rootFrame->GetContent(), nullptr); const IntersectionOutput output =
DOMIntersectionObserver::Intersect(input, *aContainingBlock);
if (intersectionRect.isNothing()) {
LOG(" The intersectionRect is nothing for Element=%p. return.",
aContainingBlock); return;
}
// Let intersectingClientContentRect be the intersection of clientContentRect // with intersectionRect.
Maybe<nsRect> intersectionWithContentRect =
clientContentRect.EdgeInclusiveIntersection(intersectionRect.value());
if (intersectionWithContentRect.isNothing()) {
LOG(" The intersectionWithContentRect is nothing for Element=%p. return.",
aContainingBlock); return;
}
LOG(" Viewport = %f, RenderRect = %f.", viewport, area); // We don't want to report things that take the entire viewport. if (area >= viewport) {
LOG(" The renderedRect is at least same as the area of the " "viewport for Element=%p, return.",
aContainingBlock); return;
}
if (aIsImage && hasIntrinsicSize) { // Let (naturalWidth, naturalHeight) be imageRequest’s natural dimension. // Let naturalArea be naturalWidth * naturalHeight. double naturalArea =
GetAreaInDoublePixelsFromAppUnits(intrinsicSize.value());
// Let scaleFactor be boundingClientArea / naturalArea. double scaleFactor = boundingClientArea / naturalArea;
LOG(" scaleFactor = %f", scaleFactor);
// If scaleFactor is greater than 1, then divide area by scaleFactor. if (scaleFactor > 1) {
LOG(" area before sacled doown %f", area);
area = area / scaleFactor;
}
}
Element* containingBlock =
LargestContentfulPaint::GetContainingBlockForTextFrame(aTextFrame); if (!containingBlock || // If element is contained in doc’s set of elements with rendered text, // continue
containingBlock->HasFlag(ELEMENT_PROCESSED_BY_LCP_FOR_TEXT) ||
containingBlock->ChromeOnlyAccess()) { return;
}
MOZ_ASSERT(containingBlock->GetPrimaryFrame());
PerformanceMainThread* perf =
aTextFrame->PresContext()->GetPerformanceMainThread(); if (!perf) { return;
}
entry->UpdateSize(aContainingBlock, aTargetRectRelativeToSelf, aPerformance, false); // If area is less than or equal to document’s largest contentful paint size, // return. if (!aPerformance->UpdateLargestContentfulPaintSize(entry->Size())) {
LOG(" This paint(%lu) is not greater than the largest paint (%lf)that " "we've " "reported so far, return",
entry->Size(), aPerformance->GetLargestContentfulPaintSize()); return;
}
entry->QueueEntry();
}
void LargestContentfulPaint::ReportLCPToNavigationTimings() {
nsCOMPtr<Element> element = do_QueryReferent(mElement); if (!element) { return;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.