Bug 1433336 - Collect only documents which are observerd by IntersectionObserver in nsRefreshDriver::Tick(). r?smaug
We don't need to collect whole descendants documents.
This patch intentionally leaves animation events handling which is another
caller of CollectDocuments in nsRefreshDriver since the animation part will
be fixed in a different way in
bug 1415780.
MozReview-Commit-ID: INAJm1NHLuI
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -615,16 +615,20 @@ public:
virtual void AddIntersectionObserver(
mozilla::dom::DOMIntersectionObserver* aObserver) override;
virtual void RemoveIntersectionObserver(
mozilla::dom::DOMIntersectionObserver* aObserver) override;
virtual void UpdateIntersectionObservations() override;
virtual void ScheduleIntersectionObserverNotification() override;
virtual void NotifyIntersectionObservers() override;
+ virtual bool HasIntersectionObservers() const override
+ {
+ return !mIntersectionObservers.IsEmpty();
+ }
virtual void NotifyLayerManagerRecreated() override;
virtual void ScheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) override;
virtual void UnscheduleSVGForPresAttrEvaluation(nsSVGElement* aSVG) override;
virtual void ResolveScheduledSVGPresAttrs() override;
bool IsSynthesized();
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3115,16 +3115,17 @@ public:
virtual void AddIntersectionObserver(
mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
virtual void RemoveIntersectionObserver(
mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
virtual void UpdateIntersectionObservations() = 0;
virtual void ScheduleIntersectionObserverNotification() = 0;
virtual void NotifyIntersectionObservers() = 0;
+ virtual bool HasIntersectionObservers() const = 0;
// Dispatch a runnable related to the document.
virtual nsresult Dispatch(mozilla::TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable) override;
virtual nsISerialEventTarget*
EventTargetFor(mozilla::TaskCategory aCategory) const override;
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1583,16 +1583,38 @@ CollectDocuments(nsIDocument* aDocument,
{
static_cast<AutoTArray<nsCOMPtr<nsIDocument>, 32>*>(aDocArray)->
AppendElement(aDocument);
aDocument->EnumerateSubDocuments(CollectDocuments, aDocArray);
return true;
}
void
+nsRefreshDriver::UpdateIntersectionObservations()
+{
+ AutoTArray<nsCOMPtr<nsIDocument>, 32> documents;
+
+ if (mPresContext->Document()->HasIntersectionObservers()) {
+ documents.AppendElement(mPresContext->Document());
+ }
+
+ mPresContext->Document()->CollectDescendantDocuments(
+ documents,
+ [](const nsIDocument* document) -> bool {
+ return document->HasIntersectionObservers();
+ });
+
+ for (uint32_t i = 0; i < documents.Length(); ++i) {
+ nsIDocument* doc = documents[i];
+ doc->UpdateIntersectionObservations();
+ doc->ScheduleIntersectionObserverNotification();
+ }
+}
+
+void
nsRefreshDriver::DispatchAnimationEvents()
{
if (!mPresContext) {
return;
}
AutoTArray<nsCOMPtr<nsIDocument>, 32> documents;
CollectDocuments(mPresContext->Document(), &documents);
@@ -1950,23 +1972,17 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
// Update any popups that may need to be moved or hidden due to their
// anchor changing.
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
pm->UpdatePopupPositions(this);
}
#endif
- AutoTArray<nsCOMPtr<nsIDocument>, 32> documents;
- CollectDocuments(mPresContext->Document(), &documents);
- for (uint32_t i = 0; i < documents.Length(); ++i) {
- nsIDocument* doc = documents[i];
- doc->UpdateIntersectionObservations();
- doc->ScheduleIntersectionObserverNotification();
- }
+ UpdateIntersectionObservations();
/*
* Perform notification to imgIRequests subscribed to listen
* for refresh events.
*/
for (auto iter = mStartTable.Iter(); !iter.Done(); iter.Next()) {
const uint32_t& delay = iter.Key();
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -380,16 +380,17 @@ private:
mozilla::Maybe<mozilla::TimeStamp> mStartTime;
RequestTable mEntries;
};
typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable;
void DispatchPendingEvents();
void DispatchAnimationEvents();
void RunFrameRequestCallbacks(mozilla::TimeStamp aNowTime);
+ void UpdateIntersectionObservations();
void Tick(int64_t aNowEpoch, mozilla::TimeStamp aNowTime);
enum EnsureTimerStartedFlags {
eNone = 0,
eForceAdjustTimer = 1 << 0,
eAllowTimeToGoBackwards = 1 << 1,
eNeverAdjustTimer = 1 << 2,
};