Changeset 215070 in webkit


Ignore:
Timestamp:
Apr 6, 2017 5:04:10 PM (7 years ago)
Author:
Simon Fraser
Message:

Throttle requestAnimationFrame in cross-origin iframes to 30fps
https://bugs.webkit.org/show_bug.cgi?id=170534

Reviewed by Dan Bates.

Source/WebCore:

Add a throttling reason to ScriptedAnimationController which is NonInteractedCrossOriginFrame,
set on cross-origin iframes whose documents have never seen a user interaction. It's cleared
as soon as an interaction on this frame or a child frame is detected.

Move the initialization of the LowPowerMode throttling reason to Document::requestAnimationFrame(),
since it's more appropriate to compute NonInteractedCrossOriginFrame here than down in ScriptedAnimationController,
and best to do both in the same place.

Tests: http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe.html

  • dom/Document.cpp:

(WebCore::Document::requestAnimationFrame):
(WebCore::Document::updateLastHandledUserGestureTimestamp):

  • dom/Document.h:

(WebCore::Document::hasHadUserInteraction):

  • dom/ScriptedAnimationController.cpp:

(WebCore::ScriptedAnimationController::ScriptedAnimationController):
(WebCore::throttlingReasonToString):
(WebCore::ScriptedAnimationController::interval):

  • dom/ScriptedAnimationController.h:
  • loader/FrameLoader.cpp:

(WebCore::shouldAskForNavigationConfirmation):

LayoutTests:

  • http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe-expected.txt: Added.
  • http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe.html: Added.
  • http/tests/frame-throttling/resources/requestAnimationFrame-frame.html: Added.
Location:
trunk
Files:
5 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r215067 r215070  
     12017-04-05  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Throttle requestAnimationFrame in cross-origin iframes to 30fps
     4        https://bugs.webkit.org/show_bug.cgi?id=170534
     5
     6        Reviewed by Dan Bates.
     7
     8        * http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe-expected.txt: Added.
     9        * http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe.html: Added.
     10        * http/tests/frame-throttling/resources/requestAnimationFrame-frame.html: Added.
     11
    1122017-04-06  Ryan Haddad  <ryanhaddad@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r215069 r215070  
     12017-04-05  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Throttle requestAnimationFrame in cross-origin iframes to 30fps
     4        https://bugs.webkit.org/show_bug.cgi?id=170534
     5
     6        Reviewed by Dan Bates.
     7
     8        Add a throttling reason to ScriptedAnimationController which is NonInteractedCrossOriginFrame,
     9        set on cross-origin iframes whose documents have never seen a user interaction. It's cleared
     10        as soon as an interaction on this frame or a child frame is detected.
     11
     12        Move the initialization of the LowPowerMode throttling reason to Document::requestAnimationFrame(),
     13        since it's more appropriate to compute NonInteractedCrossOriginFrame here than down in ScriptedAnimationController,
     14        and best to do both in the same place.
     15
     16        Tests: http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe.html
     17
     18        * dom/Document.cpp:
     19        (WebCore::Document::requestAnimationFrame):
     20        (WebCore::Document::updateLastHandledUserGestureTimestamp):
     21        * dom/Document.h:
     22        (WebCore::Document::hasHadUserInteraction):
     23        * dom/ScriptedAnimationController.cpp:
     24        (WebCore::ScriptedAnimationController::ScriptedAnimationController):
     25        (WebCore::throttlingReasonToString):
     26        (WebCore::ScriptedAnimationController::interval):
     27        * dom/ScriptedAnimationController.h:
     28        * loader/FrameLoader.cpp:
     29        (WebCore::shouldAskForNavigationConfirmation):
     30
    1312017-04-05  Simon Fraser  <simon.fraser@apple.com>
    232
  • trunk/Source/WebCore/dom/Document.cpp

    r214982 r215070  
    60126012            m_scriptedAnimationController->suspend();
    60136013
     6014        if (page() && page()->isLowPowerModeEnabled())
     6015            m_scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::LowPowerMode);
     6016
     6017        if (!topOrigin().canAccess(securityOrigin()) && !hasHadUserInteraction())
     6018            m_scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame);
     6019
    60146020        if (settings().shouldDispatchRequestAnimationFrameEvents()) {
    60156021            if (!page())
     
    63166322{
    63176323    m_lastHandledUserGestureTimestamp = time;
     6324
     6325    if (static_cast<bool>(time) && m_scriptedAnimationController) {
     6326        // It's OK to always remove NonInteractedCrossOriginFrame even if this frame isn't cross-origin.
     6327        m_scriptedAnimationController->removeThrottlingReason(ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame);
     6328    }
    63186329   
    63196330    if (HTMLFrameOwnerElement* element = ownerElement())
  • trunk/Source/WebCore/dom/Document.h

    r214982 r215070  
    11451145
    11461146    MonotonicTime lastHandledUserGestureTimestamp() const { return m_lastHandledUserGestureTimestamp; }
     1147    bool hasHadUserInteraction() const { return static_cast<bool>(m_lastHandledUserGestureTimestamp); }
    11471148    void updateLastHandledUserGestureTimestamp(MonotonicTime);
    11481149
  • trunk/Source/WebCore/dom/ScriptedAnimationController.cpp

    r214614 r215070  
    6565{
    6666    windowScreenDidChange(displayID);
    67 
    68     auto* page = document.page();
    69     if (page && page->isLowPowerModeEnabled())
    70         addThrottlingReason(ThrottlingReason::LowPowerMode);
    7167}
    7268
     
    111107    case ScriptedAnimationController::ThrottlingReason::LowPowerMode:
    112108        return "LowPowerMode";
     109    case ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame:
     110        return "NonInteractiveCrossOriginFrame";
    113111    }
    114112}
     
    269267    if (m_throttlingReasons.contains(ThrottlingReason::VisuallyIdle) || m_throttlingReasons.contains(ThrottlingReason::OutsideViewport))
    270268        return aggressiveThrottlingAnimationInterval;
     269
    271270    if (m_throttlingReasons.contains(ThrottlingReason::LowPowerMode))
    272271        return halfSpeedThrottlingAnimationInterval;
     272
     273    if (m_throttlingReasons.contains(ThrottlingReason::NonInteractedCrossOriginFrame))
     274        return halfSpeedThrottlingAnimationInterval;
     275
    273276    ASSERT(m_throttlingReasons.isEmpty());
    274277#endif
  • trunk/Source/WebCore/dom/ScriptedAnimationController.h

    r214532 r215070  
    7474
    7575    enum class ThrottlingReason {
    76         VisuallyIdle    = 1 << 0,
    77         OutsideViewport = 1 << 1,
    78         LowPowerMode    = 1 << 2,
     76        VisuallyIdle                    = 1 << 0,
     77        OutsideViewport                 = 1 << 1,
     78        LowPowerMode                    = 1 << 2,
     79        NonInteractedCrossOriginFrame   = 1 << 3,
    7980    };
    8081    void addThrottlingReason(ThrottlingReason);
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r214944 r215070  
    30373037static bool shouldAskForNavigationConfirmation(Document& document, const BeforeUnloadEvent& event)
    30383038{
    3039     bool userDidInteractWithPage = static_cast<bool>(document.topDocument().lastHandledUserGestureTimestamp());
     3039    bool userDidInteractWithPage = document.topDocument().hasHadUserInteraction();
    30403040    // Web pages can request we ask for confirmation before navigating by:
    30413041    // - Cancelling the BeforeUnloadEvent (modern way)
Note: See TracChangeset for help on using the changeset viewer.