javascript - Does a hidden/transparent element impact rendering performance? -
so have polymer app writing. have written non-polymer web-component loading overlay can show whilst polymer loading , when app websocket connecting/reconnecting.
here exert of of css have give indication of doing:
.overlay { background: #000; bottom: 0; height: 100%; left: 0; opacity: 0; pointer-events: none; position: fixed; right: 0; transition: opacity 0.2s; top: 0; width: 100%; z-index: 9999999; } .overlay[opened] { opacity: 0.8; pointer-events: auto; } .loader { display: none; } .overlay[opened] .loader { display: block; }
now overlay , css based loader animation have used when load application realistically, if websocket disconnect shown too.
my question is, performance reasons, should removing element dom entirely , add if required? fact overlay transparent when not in use , loader animation hidden mean have no impact on drawing performance?
note: looking avoid "don't micro-optimise" answer if possible ;)
tl;dr:
in general, rendered element affects page performance when changes trigger repaint on subsequent elements in dom or when triggers resize
on parent(s), resize
can expensive being fired 100 times/second, depending on device.
as long changes element not trigger repaint on subsequent elements in dom tree, difference between having rendered, hidden behind opaque element (or above content, opacity:0
, pointer-events:none
) , having not displayed @ insignificant.
changes element will not trigger repaint on itself, because has position:fixed
. same true if had position:absolute
or if changes made through properties not trigger repaint on subsequent siblings, transform
, opacity
.
unless loader heavy on rendering engine (which case — think webgl loaders 3d scenes, materials , lights mapping — in case better not display when not shown user), difference small real challenge measure difference, performance wise.
in fact, not surprised if having rendered , changing opacity
, pointer-events
properties not, overall, less expensive toggling display
property, because browser doesn't have add/remove dom each time turn on/off. but, again, real question is: how measure it?
edit: actually, made small testing tool, 10k modals. got following results, in chrome, on linux:
`opacity` average: 110.71340000000076ms | count: 100 `display` average: 155.47145000000017ms | count: 100
... assumption correct: display
more expensive overall.
the opacity
changes around 110ms
few exceptions, while display
changes faster when nodes removed slower when added.
feel free test yourself, in different browsers, on different systems:
$(window).on('load', function () { let displayavg = 0, displaycount = 0, opacityavg = 0, opacitycount = 0; (let = 0; < 10000; i++) { $('body').append($('<div />', { class: 'modal', html:'10k × modal instances' })) } $(document) .on('click', '#display', function () { $('.modal').removeclass('opacity'); let t0 = performance.now(); $('.modal').toggleclass('display'); settimeout(function () { let t1 = performance.now(); displayavg += (t1 - t0); console.log( '`display` toggle took ' + (t1 - t0) + 'ms \n`display` average: ' + (displayavg / ++displaycount) + 'ms | count: ' + displaycount ); }) }) .on('click', '#opacity', function () { $('.modal').removeclass('display'); let t0 = performance.now(); $('.modal').toggleclass('opacity'); settimeout(function () { let t1 = performance.now(); opacityavg += (t1 - t0); console.log( '`opacity` + `pointer-events` toggle took ' + (t1 - t0) + 'ms \n`opacity` average: ' + (opacityavg / ++opacitycount) + 'ms | count: ' + opacitycount ); }); }) });
body { margin: 0; } .buttons-wrapper { position: relative; z-index: 1; margin-top: 3rem; } .modal { height: 100vh; width: 100vw; position: fixed; top: 0; left: 0; padding: 1rem; } .modal.display { display: none; } .modal.opacity { opacity: 0; pointer-events: none; } .as-console-wrapper { z-index: 2; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="buttons-wrapper"> <button id="display">toggle `display`</button> <button id="opacity">toggle `opacity` + `pointer-events`</button> </div>
but average 10k elements. divide 10k , it's virtually no difference @ all: we're talking less 0.45% of millisecond.
Comments
Post a Comment