Bug 1369662 - Make tabpaint talos test rely on MozAfterPaint paint timestamps as opposed to event processing timestamps. r?jmaher draft
authorMike Conley <mconley@mozilla.com>
Thu, 08 Jun 2017 11:27:46 -0400
changeset 591098 50271b13d2edf345d647bc19c90a2f2a96441896
parent 590258 fb40bcb6155bd1e3ac5468ff4575cce171efbc12
child 632430 ca862ac6079d42b56b4801591aaf1c3b9926c968
push id62960
push usermconley@mozilla.com
push dateThu, 08 Jun 2017 17:25:53 +0000
reviewersjmaher
bugs1369662, 1371332
milestone55.0a1
Bug 1369662 - Make tabpaint talos test rely on MozAfterPaint paint timestamps as opposed to event processing timestamps. r?jmaher Also bypasses bug 1371332 by ignoring MozAfterPaint events with empty rects. MozReview-Commit-ID: GSBlPSrQxo9
testing/talos/talos/tests/tabpaint/content/target.html
testing/talos/talos/tests/tabpaint/install.rdf
testing/talos/talos/tests/tabpaint/tabpaint-signed.xpi
--- a/testing/talos/talos/tests/tabpaint/content/target.html
+++ b/testing/talos/talos/tests/tabpaint/content/target.html
@@ -9,29 +9,56 @@
 <script>
   const { classes: Cc, interfaces: Ci } = Components;
 
   /**
    * When this page is loaded, we expect a search string to be
    * appended with the "starting time" (in ms) of when the tab
    * was opened.
    *
-   * Example: target.htmml?1457063506846
+   * Example: target.html?1457063506846
    */
-  addEventListener("load", function onLoad() {
-    removeEventListener("load", onLoad);
-    addEventListener("MozAfterPaint", function onPaint() {
-      let presented = Date.now();
-      removeEventListener("MozAfterPaint", onPaint);
+  addEventListener("MozAfterPaint", function onPaint(e) {
+    // Bug 1371332 - sometimes, MozAfterPaint events fire
+    // for "empty" paints, where nothing has actually been
+    // painted. We can detect that by looking at the rect
+    // for the region that has painted.
+    let rect = e.boundingClientRect;
+    if (!rect.width && !rect.height) {
+      return;
+    }
+    // The MozAfterPaint event comes with a paintTimeStamp
+    // which tells us when in this content's lifetime the
+    // paint actually occurred. Note that this is not a
+    // measurement of when this paint occurred from
+    // the UNIX epoch. This makes it a little tricky to
+    // calculate when the paint actually occurred relative
+    // to the starting time that's been appended to the
+    // page's URL.
+    //
+    // Thankfully, the PerformanceTiming API gives us a
+    // sense of when this page's lifetime started, relative
+    // to the UNIX epoch - the "fetchStart". Taking that
+    // time and adding the paintTimeStamp should give us
+    // a pretty decent approximation of when since the
+    // UNIX epoch the paint actually occurred for this
+    // content.
+    //
+    // We can then subtract the starting time to get the
+    // delta, which should now represent the time it took
+    // from requesting that the tab be opened, to the
+    // paint occurring within the tab.
+    let fetchStart = window.performance.timing.fetchStart;
+    let presented = fetchStart + e.paintTimeStamp;
+    removeEventListener("MozAfterPaint", onPaint);
 
-      let opened = parseInt(location.search.substring(1), 10);
-      let delta = presented - opened;
+    let opened = parseInt(location.search.substring(1), 10);
+    let delta = presented - opened;
 
-      let mm = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                     .getInterface(Ci.nsIWebNavigation)
-                     .QueryInterface(Ci.nsIInterfaceRequestor)
-                     .getInterface(Ci.nsIContentFrameMessageManager);
+    let mm = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                   .getInterface(Ci.nsIWebNavigation)
+                   .QueryInterface(Ci.nsIInterfaceRequestor)
+                   .getInterface(Ci.nsIContentFrameMessageManager);
 
-      mm.sendAsyncMessage("TabPaint:Painted", { delta });
-    });
+    mm.sendAsyncMessage("TabPaint:Painted", { delta });
   });
 </script>
 </html>
\ No newline at end of file
--- a/testing/talos/talos/tests/tabpaint/install.rdf
+++ b/testing/talos/talos/tests/tabpaint/install.rdf
@@ -1,15 +1,15 @@
 <?xml version="1.0"?>
 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
   <Description about="urn:mozilla:install-manifest">
     <em:id>tabpaint-test@mozilla.org</em:id>
     <em:type>2</em:type>
     <em:name>tabpaint test</em:name>
-    <em:version>1.0.2</em:version>
+    <em:version>1.0.5</em:version>
     <em:bootstrap>true</em:bootstrap>
     <em:description>Measures the performance of opening tabs</em:description>
     <em:creator>Mike Conley</em:creator>
     <em:multiprocessCompatible>true</em:multiprocessCompatible>
 
     <!-- Desktop -->
     <em:targetApplication>
       <Description>
index ecc540cc7a23d0216b3e80199865fdd1021e43f6..2591b33a2fc4cb4132e359078a3d5426c5ca50f1
GIT binary patch
literal 10561
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
JQ}W+N{|8TYzKs9?