browser_reflowPseudoelements.js (10659B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // XXX: We can consolidate this once bug 1930955 lands 7 // eslint-disable-next-line no-unused-vars 8 const perfMetadata = { 9 owner: "Accessibility Team", 10 name: "browser_reflowPseudoelements.js", 11 description: 12 "Audit a11y performance when reflowing a table containing 15000 pseudoelements.", 13 options: { 14 default: { 15 extra_args: ["headless"], 16 manifest: "perftest.toml", 17 manifest_flavor: "browser-chrome", 18 perfherder: true, 19 perfherder_metrics: [ 20 // Total time for the entire run (this probe is not process specific) 21 { 22 name: "A11Y_TotalTime", 23 unit: "ms", 24 alertThreshold: 5.0, 25 shouldAlert: true, 26 }, 27 28 //////////////// PARENT PROCESS 29 30 // Timing metrics 31 { name: "A11Y_DoInitialUpdate_parent", unit: "ms", shouldAlert: false }, 32 { 33 name: "A11Y_ProcessQueuedCacheUpdate_parent", 34 unit: "ms", 35 shouldAlert: false, 36 }, 37 { 38 name: "A11Y_ContentRemovedNode_parent", 39 unit: "ms", 40 shouldAlert: false, 41 }, 42 { 43 name: "A11Y_ContentRemovedAcc_parent", 44 unit: "ms", 45 shouldAlert: false, 46 }, 47 { 48 name: "A11Y_PruneOrInsertSubtree_parent", 49 unit: "ms", 50 shouldAlert: false, 51 }, 52 { 53 name: "A11Y_ShutdownChildrenInSubtree_parent", 54 unit: "ms", 55 shouldAlert: false, 56 }, 57 { name: "A11Y_ShowEvent_parent", unit: "ms", shouldAlert: false }, 58 { name: "A11Y_RecvCache_parent", unit: "ms", shouldAlert: false }, 59 { 60 name: "A11Y_ProcessShowEvent_parent", 61 unit: "ms", 62 shouldAlert: false, 63 }, 64 { name: "A11Y_CoalesceEvents_parent", unit: "ms", shouldAlert: false }, 65 { 66 name: "A11Y_CoalesceMutationEvents_parent", 67 unit: "ms", 68 shouldAlert: false, 69 }, 70 { 71 name: "A11Y_ProcessHideEvent_parent", 72 unit: "ms", 73 shouldAlert: false, 74 }, 75 { name: "A11Y_SendCache_parent", unit: "ms", shouldAlert: false }, 76 { name: "A11Y_WillRefresh_parent", unit: "ms", shouldAlert: false }, 77 { 78 name: "A11Y_AccessibilityServiceInit_parent", 79 unit: "ms", 80 shouldAlert: false, 81 }, 82 { 83 name: "A11Y_PlatformShowHideEvent_parent", 84 unit: "ms", 85 shouldAlert: false, 86 }, 87 // Occurrance metrics 88 { 89 name: "A11Y_DoInitialUpdate_Count_parent", 90 unit: "iterations", 91 shouldAlert: false, 92 }, 93 { 94 name: "A11Y_ProcessQueuedCacheUpdate_Count_parent", 95 unit: "iterations", 96 shouldAlert: false, 97 }, 98 { 99 name: "A11Y_ContentRemovedNode_Count_parent", 100 unit: "iterations", 101 shouldAlert: false, 102 }, 103 { 104 name: "A11Y_ContentRemovedAcc_Count_parent", 105 unit: "iterations", 106 shouldAlert: false, 107 }, 108 { 109 name: "A11Y_PruneOrInsertSubtree_Count_parent", 110 unit: "iterations", 111 shouldAlert: false, 112 }, 113 { 114 name: "A11Y_ShutdownChildrenInSubtree_Count_parent", 115 unit: "iterations", 116 shouldAlert: false, 117 }, 118 { 119 name: "A11Y_ShowEvent_Count_parent", 120 unit: "iterations", 121 shouldAlert: false, 122 }, 123 { 124 name: "A11Y_RecvCache_Count_parent", 125 unit: "iterations", 126 shouldAlert: false, 127 }, 128 { 129 name: "A11Y_ProcessShowEvent_Count_parent", 130 unit: "iterations", 131 shouldAlert: false, 132 }, 133 { 134 name: "A11Y_CoalesceEvents_Count_parent", 135 unit: "iterations", 136 shouldAlert: false, 137 }, 138 { 139 name: "A11Y_CoalesceMutationEvents_Count_parent", 140 unit: "iterations", 141 shouldAlert: false, 142 }, 143 { 144 name: "A11Y_ProcessHideEvent_Count_parent", 145 unit: "iterations", 146 shouldAlert: false, 147 }, 148 { 149 name: "A11Y_SendCache_Count_parent", 150 unit: "iterations", 151 shouldAlert: false, 152 }, 153 { 154 name: "A11Y_WillRefresh_Count_parent", 155 unit: "iterations", 156 shouldAlert: false, 157 }, 158 { 159 name: "A11Y_AccessibilityServiceInit_Count_parent", 160 unit: "iterations", 161 shouldAlert: false, 162 }, 163 { 164 name: "A11Y_PlatformShowHideEvent_Count_parent", 165 unit: "iterations", 166 shouldAlert: false, 167 }, 168 169 //////////////// CONTENT PROCESS 170 171 // Timing metrics 172 { 173 name: "A11Y_DoInitialUpdate_content", 174 unit: "ms", 175 shouldAlert: false, 176 }, 177 { 178 name: "A11Y_ProcessQueuedCacheUpdate_content", 179 unit: "ms", 180 shouldAlert: false, 181 }, 182 { 183 name: "A11Y_ContentRemovedNode_content", 184 unit: "ms", 185 shouldAlert: false, 186 }, 187 { 188 name: "A11Y_ContentRemovedAcc_content", 189 unit: "ms", 190 shouldAlert: false, 191 }, 192 { 193 name: "A11Y_PruneOrInsertSubtree_content", 194 unit: "ms", 195 shouldAlert: false, 196 }, 197 { 198 name: "A11Y_ShutdownChildrenInSubtree_content", 199 unit: "ms", 200 shouldAlert: false, 201 }, 202 { name: "A11Y_ShowEvent_content", unit: "ms", shouldAlert: false }, 203 { name: "A11Y_RecvCache_content", unit: "ms", shouldAlert: false }, 204 { 205 name: "A11Y_ProcessShowEvent_content", 206 unit: "ms", 207 shouldAlert: false, 208 }, 209 { name: "A11Y_CoalesceEvents_content", unit: "ms", shouldAlert: false }, 210 { 211 name: "A11Y_CoalesceMutationEvents_content", 212 unit: "ms", 213 shouldAlert: false, 214 }, 215 { 216 name: "A11Y_ProcessHideEvent_content", 217 unit: "ms", 218 shouldAlert: false, 219 }, 220 { name: "A11Y_SendCache_content", unit: "ms", shouldAlert: false }, 221 { name: "A11Y_WillRefresh_content", unit: "ms", shouldAlert: false }, 222 { 223 name: "A11Y_AccessibilityServiceInit_content", 224 unit: "ms", 225 shouldAlert: false, 226 }, 227 { 228 name: "A11Y_PlatformShowHideEvent_content", 229 unit: "ms", 230 shouldAlert: false, 231 }, 232 // Occurrance metrics 233 { 234 name: "A11Y_DoInitialUpdate_Count_content", 235 unit: "iterations", 236 shouldAlert: false, 237 }, 238 { 239 name: "A11Y_ProcessQueuedCacheUpdate_Count_content", 240 unit: "iterations", 241 shouldAlert: false, 242 }, 243 { 244 name: "A11Y_ContentRemovedNode_Count_content", 245 unit: "iterations", 246 shouldAlert: false, 247 }, 248 { 249 name: "A11Y_ContentRemovedAcc_Count_content", 250 unit: "iterations", 251 shouldAlert: false, 252 }, 253 { 254 name: "A11Y_PruneOrInsertSubtree_Count_content", 255 unit: "iterations", 256 shouldAlert: false, 257 }, 258 { 259 name: "A11Y_ShutdownChildrenInSubtree_Count_content", 260 unit: "iterations", 261 shouldAlert: false, 262 }, 263 { 264 name: "A11Y_ShowEvent_Count_content", 265 unit: "iterations", 266 shouldAlert: false, 267 }, 268 { 269 name: "A11Y_RecvCache_Count_content", 270 unit: "iterations", 271 shouldAlert: false, 272 }, 273 { 274 name: "A11Y_ProcessShowEvent_Count_content", 275 unit: "iterations", 276 shouldAlert: false, 277 }, 278 { 279 name: "A11Y_CoalesceEvents_Count_content", 280 unit: "iterations", 281 shouldAlert: false, 282 }, 283 { 284 name: "A11Y_CoalesceMutationEvents_Count_content", 285 unit: "iterations", 286 shouldAlert: false, 287 }, 288 { 289 name: "A11Y_ProcessHideEvent_Count_content", 290 unit: "iterations", 291 shouldAlert: false, 292 }, 293 { 294 name: "A11Y_SendCache_Count_content", 295 unit: "iterations", 296 shouldAlert: false, 297 }, 298 { 299 name: "A11Y_WillRefresh_Count_content", 300 unit: "iterations", 301 shouldAlert: false, 302 }, 303 { 304 name: "A11Y_AccessibilityServiceInit_Count_content", 305 unit: "iterations", 306 shouldAlert: false, 307 }, 308 { 309 name: "A11Y_PlatformShowHideEvent_Count_content", 310 unit: "iterations", 311 shouldAlert: false, 312 }, 313 ], 314 try_platform: ["linux", "mac", "win"], 315 verbose: true, 316 }, 317 }, 318 }; 319 320 addAccessibleTask( 321 `<div id="container"></div> 322 <style> 323 .row::before { 324 content: attr(data-number); 325 } 326 </style>`, 327 async function testRemoveManySpellingErrors(browser) { 328 // populate the container with pseudoelements 329 const reorder = waitForEvent(EVENT_REORDER, "container"); 330 await invokeContentTask(browser, [], () => { 331 const container = content.document.getElementById("container"); 332 for (let i = 0; i < 15000; i++) { 333 const newRow = content.document.createElement("div"); 334 newRow.setAttribute("id", "data" + i); 335 newRow.setAttribute("class", "row"); 336 newRow.setAttribute("data-number", i); 337 container.appendChild(newRow); 338 } 339 }); 340 info("Waiting for container's EVENT_REORDER."); 341 await reorder; 342 343 await timeThis(async () => { 344 info("Reflowing..."); 345 await invokeContentTask(browser, [], () => { 346 // We use the following to trigger reflow. 347 content.document.body.style.display = "flex"; 348 content.document.offsetHeight; 349 }); 350 await waitForContentPaint(browser); 351 352 const show = waitForEvent(EVENT_SHOW, "lastRow"); 353 await invokeContentTask(browser, [], () => { 354 // Add a discernable "last row" so we can use its show event as a 355 // marker for "all table content is rendered". 356 const container = content.document.getElementById("container"); 357 const lastRow = content.document.createElement("div"); 358 lastRow.innerText = "I am the last row"; 359 lastRow.setAttribute("id", "lastRow"); 360 container.appendChild(lastRow); 361 }); 362 await show; 363 info("Last row has been shown after reflow."); 364 }); 365 } 366 );