test_viewport_scrollbar_causing_reflow.html (4787B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=1367568 5 --> 6 <head> 7 <meta charset="utf-8"> 8 <title>Test for Bug 1367568</title> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 11 </head> 12 <body> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug 1367568</a> 14 <div id="content"> 15 <!-- Some fixed-width divs that we shouldn't have to reflow when the viewport 16 changes. More than 5 so that our leeway for scrollbar parts doesn't 17 accidentally cause the test to pass --> 18 <div style="width: 100px">fixed-width <div>(child)</div></div> 19 <div style="width: 100px">fixed-width <div>(child)</div></div> 20 <div style="width: 100px">fixed-width <div>(child)</div></div> 21 <div style="width: 100px">fixed-width <div>(child)</div></div> 22 <div style="width: 100px">fixed-width <div>(child)</div></div> 23 <div style="width: 100px">fixed-width <div>(child)</div></div> 24 <div style="position: absolute; width: 150px"> 25 abs-fixed-width 26 <div>(child)</div> 27 </div> 28 </div> 29 <pre id="test"> 30 <script> 31 "use strict"; 32 33 /** Test for Bug 1367568 */ 34 35 /** 36 * This test verifies that "overflow" changes on the <body> don't cause 37 * an unnecessarily large amount of reflow. 38 */ 39 40 // Vars used in setStyleAndMeasure that we really only have to look up once: 41 const gUtils = SpecialPowers.getDOMWindowUtils(window); 42 43 function setStyleAndMeasure(initialStyle, finalStyle) { 44 is(document.body.style.length, 0, 45 "Bug in test - body should start with empty style"); 46 let unusedVal = document.body.offsetHeight; // flush layout 47 let constructCount = gUtils.framesConstructed; 48 49 document.body.style = initialStyle; 50 unusedVal = document.body.offsetHeight; // flush layout 51 let reflowCountBeforeTweak = gUtils.framesReflowed; 52 53 document.body.style = finalStyle; 54 unusedVal = document.body.offsetHeight; // flush layout 55 let reflowCountAfterTweak = gUtils.framesReflowed; 56 57 // Clean up: 58 document.body.style = ""; 59 60 is(gUtils.framesConstructed, constructCount, 61 "Style tweak shouldn't have triggered frame construction"); 62 63 // ...and return the delta: 64 return reflowCountAfterTweak - reflowCountBeforeTweak; 65 } 66 67 function main() { 68 // First, we sanity-check that our measurement make sense -- if we leave 69 // styles unchanged, we should measure no frames being reflowed: 70 let count = setStyleAndMeasure("width: 50px; height: 80px", 71 "width: 50px; height: 80px"); 72 is(count, 0, 73 "Shouldn't reflow anything when we leave 'width' & 'height' unchanged"); 74 75 // Now: see how many frames are reflowed when the "width" & "height" change. 76 // We'll use this as the reference when measuring reflow counts for various 77 // changes to "overflow" below. 78 count = setStyleAndMeasure("width: 50px; height: 80px", 79 "width: 90px; height: 60px"); 80 ok(count > 0, 81 "Should reflow some frames when 'width' & 'height' change"); 82 83 const scrollbarsHaveButtons = navigator.platform.includes("Win"); 84 // This is to allow for reflowing scrollbar parts themselves. 85 const scrollbarReflows = scrollbarsHaveButtons ? 5 : 2; 86 // Expected maximum number of frames reflowed for "overflow" changes 87 const expectedMax = count + scrollbarReflows; 88 89 // Shared ending for messages in all ok() checks below: 90 const messageSuffix = 91 " shouldn't be greater than count for tweaking width/height on body (" + 92 expectedMax + ")"; 93 94 // OK, here is where the relevant tests actually begin!! 95 // See how many frames we reflow for various tweaks to "overflow" on 96 // the body -- we expect the count to be no larger than |expectedMax|. 97 count = setStyleAndMeasure("", "overflow: scroll"); 98 ok(count <= expectedMax, 99 "Reflow count when setting 'overflow: scroll' on body (" + count + ")" + 100 messageSuffix); 101 102 count = setStyleAndMeasure("", "overflow: hidden"); 103 ok(count <= expectedMax, 104 "Reflow count when setting 'overflow: hidden' on body (" + count + ")" + 105 messageSuffix); 106 107 // Test removal of "overflow: scroll": 108 count = setStyleAndMeasure("overflow: scroll", ""); 109 ok(count <= expectedMax, 110 "Reflow count when removing 'overflow: scroll' from body (" + count + ")" + 111 messageSuffix); 112 113 count = setStyleAndMeasure("overflow: hidden", ""); 114 ok(count <= expectedMax, 115 "Reflow count when removing 'overflow: hidden' from body (" + count + ")" + 116 messageSuffix); 117 118 // Test change between two non-'visible' overflow values: 119 count = setStyleAndMeasure("overflow: scroll", "overflow: hidden"); 120 ok(count <= expectedMax, 121 "Reflow count when changing 'overflow' on body (" + count + ")" + 122 messageSuffix); 123 } 124 125 main(); 126 127 </script> 128 </pre> 129 </body> 130 </html>