tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_update.html (4530B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <title>Service worker performance test: update</title>
      5 </head>
      6 <div id="content"></div>
      7 <script src="/tests/SimpleTest/SimpleTest.js"></script>
      8 <script src="../utils.js"></script>
      9 <script src="perfutils.js"></script>
     10 <script>
     11 
     12  "use strict";
     13 
     14  const VACUOUS_UPDATE = "Vacuous update";
     15  const SERVER_UPDATE = "Server update";
     16  const MAIN_CALLBACK = "Main callback";
     17  const SW_CALLBACK = "SW callback";
     18  const UPDATE_INTERNALS = "Update internals";
     19 
     20  var journal = {};
     21  journal[VACUOUS_UPDATE] = [];
     22  journal[SERVER_UPDATE] = [];
     23  journal[MAIN_CALLBACK] = [];
     24  journal[SW_CALLBACK] = [];
     25  journal[UPDATE_INTERNALS] = [];
     26 
     27  const ITERATIONS = 11;
     28 
     29  var perfMetadata = {
     30    owner: "DOM LWS",
     31    name: "Service Worker Update",
     32    description: "Test updating.",
     33    options: {
     34      default: {
     35        perfherder: true,
     36        perfherder_metrics: [
     37          // Here, we can't use the constants defined above because perfherder
     38          // grabs data from the parse tree.
     39          { name: "Vacuous update", unit: "ms", shouldAlert: true },
     40          { name: "Server update", unit: "ms", shouldAlert: true },
     41          { name: "Main callback", unit: "ms", shouldAlert: true },
     42          { name: "SW callback", unit: "ms", shouldAlert: true },
     43          { name: "Update internals", unit: "ms", shouldAlert: true },
     44        ],
     45        verbose: true,
     46        manifest: "perftest.toml",
     47        manifest_flavor: "plain",
     48      },
     49    },
     50  };
     51 
     52  async function testVacuousUpdate() {
     53    async function measure() {
     54      let reg = await navigator.serviceWorker.register("sw_empty.js");
     55      await waitForState(reg.installing, "activated");
     56 
     57      let begin_ts = performance.now();
     58      await reg.update();
     59      let end_ts = performance.now();
     60 
     61      await reg.unregister();
     62 
     63      journal[VACUOUS_UPDATE].push(end_ts - begin_ts);
     64    }
     65 
     66    for (let i = 0; i < ITERATIONS; i++) {
     67      await measure();
     68    }
     69  }
     70 
     71  async function testServerUpdate() {
     72    async function measure() {
     73      await startProfiler();
     74 
     75      let reg = await navigator.serviceWorker.register("sw_serverupdate.sjs");
     76 
     77      let promiseSW = new Promise((resolve, reject) => {
     78        window.onmessage = (e) => {
     79          is(e.data, "updatefound", "got updatefound message");
     80          resolve(performance.now());
     81        };
     82      });
     83 
     84      let callbackCounter = 0;
     85      let promiseMain = new Promise((resolve, reject) => {
     86        reg.onupdatefound = (e) => {
     87          callbackCounter++;
     88          // The first "update" happens for the original script,
     89          // and isn't what we're interested in measuring.
     90          if (callbackCounter == 2) {
     91            resolve(performance.now());
     92          }
     93        };
     94      });
     95 
     96      is(callbackCounter, 0, "no onupdatefound calls");
     97      await waitForState(reg.installing, "activated");
     98      is(callbackCounter, 1, "one onupdatefound call");
     99 
    100      let content = document.getElementById("content");
    101      let iframe = document.createElement("iframe");
    102      iframe.setAttribute("src", "./fwd_messages_upward.html");
    103      content.appendChild(iframe);
    104      await new Promise(res => iframe.onload = res);
    105 
    106      let begin_ts = performance.now();
    107      await reg.update();
    108      let endUpdate_ts = performance.now();
    109      let endMainCallback_ts = await promiseMain;
    110      let endSWCallback_ts = await promiseSW;
    111 
    112      let pdata = await stopProfiler();
    113      let internals_ms = inspectProfile(pdata, [
    114        "ServiceWorkerRegistration::Update",
    115        "ServiceWorkerRegistration::Update (inner)",
    116        "ServiceWorkerUpdateJob::AsyncExecute",
    117        "ServiceWorkerUpdateJob::Update",
    118        "ServiceWorkerUpdateJob::Install"
    119      ]);
    120 
    121      await reg.unregister();
    122 
    123      journal[SERVER_UPDATE].push(endUpdate_ts - begin_ts);
    124      journal[MAIN_CALLBACK].push(endMainCallback_ts - begin_ts);
    125      journal[SW_CALLBACK].push(endSWCallback_ts - begin_ts);
    126      journal[UPDATE_INTERNALS].push(internals_ms);
    127    }
    128 
    129    for (let i = 0; i < ITERATIONS; i++) {
    130      await measure();
    131    }
    132  }
    133 
    134  add_task(async () => {
    135    await SpecialPowers.pushPrefEnv({
    136      set: [["dom.serviceWorkers.enabled", true],
    137            ["dom.serviceWorkers.testing.enabled", true],
    138            ["dom.serviceWorkers.update_delay", 0]]
    139    });
    140 
    141    add_task(() => SpecialPowers.popPrefEnv());
    142    ok(true);
    143  });
    144 
    145  add_task(testVacuousUpdate);
    146  add_task(testServerUpdate);
    147 
    148  add_task(() => reportMetrics(journal));
    149 
    150 </script>
    151 <body>
    152 <div id="content"></div>
    153 </body>
    154 </html>