blob: 5864e31a98c8842759f2ccbddac8c4fde7332473 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LAZY_LOAD_FRAME_OBSERVER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LAZY_LOAD_FRAME_OBSERVER_H_
#include <memory>
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
class IntersectionObserver;
class IntersectionObserverEntry;
class HTMLFrameOwnerElement;
class ResourceRequest;
class Visitor;
class LazyLoadFrameObserver
: public GarbageCollectedFinalized<LazyLoadFrameObserver> {
public:
// This enum is logged to histograms, so values should not be reordered or
// reused, and it must match the corresponding enum
// "LazyLoad.FrameInitialDeferralAction" in
// tools/metrics/histograms/enums.xml.
enum class FrameInitialDeferralAction {
// The frame was not loaded immediately, and the load continued to be
// deferred.
kDeferred = 0,
// The frame was either visible or near enough to the viewport that it was
// loaded immediately.
kLoadedNearOrInViewport = 1,
// The frame was determined to likely be a hidden frame (e.g. analytics or
// communication iframes), so it was loaded immediately.
kLoadedHidden = 2,
kMaxValue = kLoadedHidden
};
explicit LazyLoadFrameObserver(HTMLFrameOwnerElement&);
~LazyLoadFrameObserver();
void DeferLoadUntilNearViewport(const ResourceRequest&, WebFrameLoadType);
bool IsLazyLoadPending() const { return lazy_load_intersection_observer_; }
void CancelPendingLazyLoad();
void StartTrackingVisibilityMetrics();
void RecordMetricsOnLoadFinished();
void LoadImmediately();
void Trace(blink::Visitor*);
private:
struct LazyLoadRequestInfo;
void LoadIfHiddenOrNearViewport(
const HeapVector<Member<IntersectionObserverEntry>>&);
void RecordMetricsOnVisibilityChanged(
const HeapVector<Member<IntersectionObserverEntry>>&);
void RecordVisibilityMetricsIfLoadedAndVisible();
void RecordInitialDeferralAction(FrameInitialDeferralAction);
const Member<HTMLFrameOwnerElement> element_;
// The intersection observer responsible for loading the frame once it's near
// the viewport.
Member<IntersectionObserver> lazy_load_intersection_observer_;
// Keeps track of the resource request and other info needed to load in the
// deferred frame. This is only non-null if there's a lazy load pending.
std::unique_ptr<LazyLoadRequestInfo> lazy_load_request_info_;
// Used to record visibility-related metrics related to lazy load. This is an
// IntersectionObserver instead of just an ElementVisibilityObserver so that
// hidden frames can be detected in order to avoid recording metrics for them.
Member<IntersectionObserver> visibility_metrics_observer_;
// Keeps track of whether this frame was initially visible on the page.
bool is_initially_above_the_fold_ = false;
bool has_above_the_fold_been_set_ = false;
// Set when the frame first becomes visible (i.e. appears in the viewport).
TimeTicks time_when_first_visible_;
// Set when the first load event is dispatched for the frame.
TimeTicks time_when_first_load_finished_;
// Keeps track of whether the frame was initially recorded as having been
// deferred, so that the appropriate histograms can be recorded if the frame
// later gets loaded in for some reason.
bool was_recorded_as_deferred_ = false;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LAZY_LOAD_FRAME_OBSERVER_H_