Bug 213344

Summary: Cross domain <iframe> animation throttling doesn't respond to touch events correctly
Product: WebKit Reporter: Dustin Kerstein <dustin.kerstein>
Component: AnimationsAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: cdumez, dino, graouts, graouts, jason, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 13   
Hardware: Unspecified   
OS: All   
See Also: https://bugs.webkit.org/show_bug.cgi?id=170534
Attachments:
Description Flags
Test none

Description Dustin Kerstein 2020-06-18 10:14:44 PDT
In this changeset - https://trac.webkit.org/changeset/215070/webkit - A throttling mechanism was introduced to prevent iFrame Ads from unnecessarily consuming battery when the user wasn't interacting with them. It defaults a cross-domain iFrame's requestAnimationFrame frequency to 30fps, until the user "interacts" with the iFrame. This appears to be working correctly with mouse events. However, touch events aren't working the same way. Ie. If you quickly tap on the iFrame, it will start rendering at 60fps. However, if you swipe/drag/pan (as in for a 360 photo for example) it won't mark this as "interacted" and stays at 30fps. Here is an easy example to replicate with.

Parent Frame
------------
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body {
          margin: 0;
          padding: 0;
          background-color: #000000; 
          overflow: hidden:;
      } 
      #text {
        width: 100%;
        height: 100%;
        position: fixed;
        font-size: 5vw;
        color: white;
        text-align: center;
        top: 50%;
      }
      #countText {
        position: fixed;
        bottom: 1em;
        right: 1em;
        color: white;
      }
    </style>
  </head>
  <body>
    <div id="text">
      Swiping doesn't trigger "interaction". Only an actual touch "tap".
    </div>
    <div id="countText">
    </div>
    <script>  
      var count = 0;
      window.requestAnimationFrame(animate);

      function animate() {
        window.requestAnimationFrame(animate);
        count++;
        document.getElementById("countText").innerHTML = count;
      }

      (function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//mrdoob.github.io/stats.js/build/stats.min.js';document.head.appendChild(script);})()
    </script>
  </body>
</html>




Child Frame
-----------
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body {
          margin: 0;
          padding: 0;
          background-color: #000000;
          overflow: hidden; 
      } 
    </style>
  </head>
  <body>
    <iframe id="iframe" width="480px" height="480px" src="http://IPADDRESS:PORT/webkitchild.html"></iframe>
    <!-- <iframe id="iframe" width="480px" height="480px" src="http://LOCALHOST:PORT/webkitchild.html"></iframe> -->
</html>

In order to replicate, you need to ensure that the URL of the Parent frame is not the same as the Child frame (ie. it has to be Cross Domain). Using the local server's IP address and Localhost should allow you to replicate on a single device without having to deal with DNS.

Maybe this is as designed, but I felt that those types of touch events (swiping, dragging, zooming, etc.) should be considered a valid interaction to bypass the throttling code. Does that sound reasonable?
Comment 1 Dustin Kerstein 2020-06-18 10:15:52 PDT
Apologies. The "Parent Frame" and "Child Frame" are labelled backwards in my previous post.
Comment 2 Radar WebKit Bug Importer 2020-06-19 17:29:43 PDT
<rdar://problem/64550446>
Comment 3 Antoine Quint 2020-07-31 06:28:16 PDT
Actually, just loading the files locally shows a cap of 30fps for the frame in the iOS Simulator.
Comment 4 Antoine Quint 2020-07-31 06:30:42 PDT
Created attachment 405684 [details]
Test

Attached the sample from the bug description as a ZIP archive, opening the 213344-parent.html shows the issue where the stats are capped at 30fps.
Comment 5 Antoine Quint 2020-07-31 06:31:32 PDT
Cc'ing Simon, who wrote the patch in question (r215070).
Comment 6 Antoine Quint 2020-07-31 10:20:33 PDT
If I add a "pointerup" event listener in the child document, the 30fps throttle is released if I tap in the document. However, if I do a different kind of gesture which does not yield a simulated "click", the 30fps remains in place.