perftest_http3_google_image.js (5185B)
1 // This Source Code Form is subject to the terms of the Mozilla Public 2 // License, v. 2.0. If a copy of the MPL was not distributed with this 3 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 /* eslint-env node */ 5 6 /* 7 Ensure the `--firefox.preference=network.http.http3.enable:true` is 8 set for this test. 9 */ 10 11 async function getNumImagesLoaded(elementSelector, commands) { 12 return commands.js.run(` 13 let sum = 0; 14 document.querySelectorAll(${elementSelector}).forEach(e => { 15 sum += e.complete & e.naturalHeight != 0; 16 }); 17 return sum; 18 `); 19 } 20 21 async function waitForImgLoadEnd( 22 prevCount, 23 maxStableCount, 24 iterationDelay, 25 timeout, 26 commands, 27 context, 28 counter, 29 elementSelector 30 ) { 31 let starttime = await commands.js.run(`return performance.now();`); 32 let endtime = await commands.js.run(`return performance.now();`); 33 let changing = true; 34 let newCount = -1; 35 let stableCount = 0; 36 37 while ( 38 ((await commands.js.run(`return performance.now();`)) - starttime < 39 timeout) & 40 changing 41 ) { 42 // Wait a bit before making another round 43 await commands.wait.byTime(iterationDelay); 44 newCount = await counter(elementSelector, commands); 45 context.log.debug(`${newCount}, ${prevCount}, ${stableCount}`); 46 47 // Check if we are approaching stability 48 if (newCount == prevCount) { 49 // Gather the end time now 50 if (stableCount == 0) { 51 endtime = await commands.js.run(`return performance.now();`); 52 } 53 stableCount++; 54 } else { 55 prevCount = newCount; 56 stableCount = 0; 57 } 58 59 if (stableCount >= maxStableCount) { 60 // Stability achieved 61 changing = false; 62 } 63 } 64 65 return { 66 start: starttime, 67 end: endtime, 68 numResources: newCount, 69 }; 70 } 71 72 async function test(context, commands) { 73 let rootUrl = "https://www.google.com/search?q=kittens&tbm=isch"; 74 let waitTime = 1000; 75 let numScrolls = 10; 76 77 const average = arr => arr.reduce((p, c) => p + c, 0) / arr.length; 78 79 if (typeof context.options.browsertime !== "undefined") { 80 if (typeof context.options.browsertime.waitTime !== "undefined") { 81 waitTime = context.options.browsertime.waitTime; 82 } 83 if (typeof context.options.browsertime.numScrolls !== "undefined") { 84 numScrolls = context.options.browsertime.numScrolls; 85 } 86 } 87 88 // Make firefox learn of HTTP/3 server 89 await commands.navigate(rootUrl); 90 91 let cycles = 1; 92 for (let cycle = 0; cycle < cycles; cycle++) { 93 // Measure the pageload 94 await commands.measure.start("pageload"); 95 await commands.navigate(rootUrl); 96 await commands.measure.stop(); 97 98 async function getHeight() { 99 return commands.js.run(`return document.body.scrollHeight;`); 100 } 101 102 let vals = []; 103 let badIterations = 0; 104 let prevHeight = 0; 105 for (let iteration = 0; iteration < numScrolls; iteration++) { 106 // Get current image count 107 let currCount = await getNumImagesLoaded(`".isv-r img"`, commands); 108 prevHeight = await getHeight(); 109 110 // Scroll to a ridiculously high value for "infinite" down-scrolling 111 commands.js.runAndWait(` 112 window.scrollTo({ top: 100000000 }) 113 `); 114 115 /* 116 The maxStableCount of 22 was chosen as a trade-off between fast iterations 117 and minimizing the number of bad iterations. 118 */ 119 let results = await waitForImgLoadEnd( 120 currCount, 121 22, 122 100, 123 120000, 124 commands, 125 context, 126 getNumImagesLoaded, 127 `".isv-r img"` 128 ); 129 130 // Gather metrics 131 let ndiff = results.numResources - currCount; 132 let tdiff = (results.end - results.start) / 1000; 133 134 // Check if we had a bad iteration 135 if (ndiff == 0) { 136 // Check if the end of the search results was reached 137 if (prevHeight == (await getHeight())) { 138 context.log.info("Reached end of page."); 139 break; 140 } 141 context.log.info("Bad iteration, redoing..."); 142 iteration--; 143 badIterations++; 144 if (badIterations == 5) { 145 throw new Error("Too many bad scroll iterations occurred"); 146 } 147 continue; 148 } 149 150 context.log.info(`${ndiff}, ${tdiff}`); 151 vals.push(ndiff / tdiff); 152 153 // Wait X seconds before scrolling again 154 await commands.wait.byTime(waitTime); 155 } 156 157 if (!vals.length) { 158 throw new Error("No requestsPerSecond values were obtained"); 159 } 160 161 commands.measure.result[0].browserScripts.pageinfo.imagesPerSecond = 162 average(vals); 163 164 // Test clicking and and opening an image 165 await commands.wait.byTime(waitTime); 166 commands.click.byJs(` 167 const links = document.querySelectorAll(".islib"); links[links.length-1] 168 `); 169 let results = await waitForImgLoadEnd( 170 0, 171 22, 172 50, 173 120000, 174 commands, 175 context, 176 getNumImagesLoaded, 177 `"#islsp img"` 178 ); 179 commands.measure.result[0].browserScripts.pageinfo.imageLoadTime = 180 results.end - results.start; 181 } 182 } 183 184 module.exports = { 185 test, 186 owner: "Network Team", 187 component: "netwerk", 188 name: "g-image", 189 description: "Measures the number of images per second after a scroll.", 190 };