зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1722968 - Add an optimization for GetAllInFlowRects to avoid expensive ancestor lookups in DOMIntersectionObserver. r=jwatt
Part of the issue with the profile in the blocked bug is that 30% of the time is spent in nsLayoutUtils::FindNearestCommonAncestorFrame from DOMIntersectionObserver::Update. That shouldn't be needed since in most cases we know we're an ancestor. We have an optimization for the root frame but DOMIntersectionObserver keeps its rects relative to `target`. So we only need to do the expensive transform for IB splits / fragmented flows. Differential Revision: https://phabricator.services.mozilla.com/D121214
This commit is contained in:
Родитель
eda5c43145
Коммит
9a783438a6
|
@ -3711,9 +3711,11 @@ void nsLayoutUtils::AddBoxesForFrame(nsIFrame* aFrame,
|
|||
|
||||
void nsLayoutUtils::GetAllInFlowBoxes(nsIFrame* aFrame,
|
||||
BoxCallback* aCallback) {
|
||||
aCallback->mInTargetContinuation = false;
|
||||
while (aFrame) {
|
||||
AddBoxesForFrame(aFrame, aCallback);
|
||||
aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
|
||||
aCallback->mInTargetContinuation = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3756,14 +3758,23 @@ struct BoxToRect : public nsLayoutUtils::BoxCallback {
|
|||
const nsIFrame* mRelativeTo;
|
||||
RectCallback* mCallback;
|
||||
uint32_t mFlags;
|
||||
// If the frame we're measuring relative to is the root, we know all frames
|
||||
// are descendants of it, so we don't need to compute the common ancestor
|
||||
// between a frame and mRelativeTo.
|
||||
bool mRelativeToIsRoot;
|
||||
// For the same reason, if the frame we're measuring relative to is the target
|
||||
// (this is useful for IntersectionObserver), we know all frames are
|
||||
// descendants of it except if we're in a continuation or ib-split-sibling of
|
||||
// it.
|
||||
bool mRelativeToIsTarget;
|
||||
|
||||
BoxToRect(const nsIFrame* aRelativeTo, RectCallback* aCallback,
|
||||
uint32_t aFlags)
|
||||
BoxToRect(const nsIFrame* aTargetFrame, const nsIFrame* aRelativeTo,
|
||||
RectCallback* aCallback, uint32_t aFlags)
|
||||
: mRelativeTo(aRelativeTo),
|
||||
mCallback(aCallback),
|
||||
mFlags(aFlags),
|
||||
mRelativeToIsRoot(!aRelativeTo->GetParent()) {}
|
||||
mRelativeToIsRoot(!aRelativeTo->GetParent()),
|
||||
mRelativeToIsTarget(aRelativeTo == aTargetFrame) {}
|
||||
|
||||
virtual void AddBox(nsIFrame* aFrame) override {
|
||||
nsRect r;
|
||||
|
@ -3785,7 +3796,8 @@ struct BoxToRect : public nsLayoutUtils::BoxCallback {
|
|||
}
|
||||
}
|
||||
if (mFlags & nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS) {
|
||||
if (mRelativeToIsRoot) {
|
||||
if (mRelativeToIsRoot ||
|
||||
(mRelativeToIsTarget && !mInTargetContinuation)) {
|
||||
r = nsLayoutUtils::TransformFrameRectToAncestor(outer, r, mRelativeTo);
|
||||
} else {
|
||||
nsLayoutUtils::TransformRect(outer, mRelativeTo, r);
|
||||
|
@ -3800,9 +3812,11 @@ struct BoxToRect : public nsLayoutUtils::BoxCallback {
|
|||
struct MOZ_RAII BoxToRectAndText : public BoxToRect {
|
||||
Sequence<nsString>* mTextList;
|
||||
|
||||
BoxToRectAndText(const nsIFrame* aRelativeTo, RectCallback* aCallback,
|
||||
Sequence<nsString>* aTextList, uint32_t aFlags)
|
||||
: BoxToRect(aRelativeTo, aCallback, aFlags), mTextList(aTextList) {}
|
||||
BoxToRectAndText(const nsIFrame* aTargetFrame, const nsIFrame* aRelativeTo,
|
||||
RectCallback* aCallback, Sequence<nsString>* aTextList,
|
||||
uint32_t aFlags)
|
||||
: BoxToRect(aTargetFrame, aRelativeTo, aCallback, aFlags),
|
||||
mTextList(aTextList) {}
|
||||
|
||||
static void AccumulateText(nsIFrame* aFrame, nsAString& aResult) {
|
||||
MOZ_ASSERT(aFrame);
|
||||
|
@ -3842,7 +3856,7 @@ void nsLayoutUtils::GetAllInFlowRects(nsIFrame* aFrame,
|
|||
const nsIFrame* aRelativeTo,
|
||||
RectCallback* aCallback,
|
||||
uint32_t aFlags) {
|
||||
BoxToRect converter(aRelativeTo, aCallback, aFlags);
|
||||
BoxToRect converter(aFrame, aRelativeTo, aCallback, aFlags);
|
||||
GetAllInFlowBoxes(aFrame, &converter);
|
||||
}
|
||||
|
||||
|
@ -3851,7 +3865,7 @@ void nsLayoutUtils::GetAllInFlowRectsAndTexts(nsIFrame* aFrame,
|
|||
RectCallback* aCallback,
|
||||
Sequence<nsString>* aTextList,
|
||||
uint32_t aFlags) {
|
||||
BoxToRectAndText converter(aRelativeTo, aCallback, aTextList, aFlags);
|
||||
BoxToRectAndText converter(aFrame, aRelativeTo, aCallback, aTextList, aFlags);
|
||||
GetAllInFlowBoxes(aFrame, &converter);
|
||||
}
|
||||
|
||||
|
|
|
@ -1241,9 +1241,13 @@ class nsLayoutUtils {
|
|||
|
||||
class BoxCallback {
|
||||
public:
|
||||
BoxCallback() : mIncludeCaptionBoxForTable(true) {}
|
||||
BoxCallback() = default;
|
||||
virtual void AddBox(nsIFrame* aFrame) = 0;
|
||||
bool mIncludeCaptionBoxForTable;
|
||||
bool mIncludeCaptionBoxForTable = true;
|
||||
// Whether we are in a continuation or ib-split-sibling of the target we're
|
||||
// measuring. This is useful because if we know we're in the target subtree
|
||||
// and measuring against it we can avoid finding the common ancestor.
|
||||
bool mInTargetContinuation = false;
|
||||
};
|
||||
/**
|
||||
* Collect all CSS boxes associated with aFrame and its
|
||||
|
|
Загрузка…
Ссылка в новой задаче