This session explains the basic concepts in browser implementations of core Web document technologies (HTML, XHTML, CSS, and SVG), explains their general performance characteristics and how they interact with Javascript, and explains common optimizations (such as coalescing changes) that browsers make. Rather than presenting specific techniques authors can use, the goal is to build understanding of the performance characteristics of the Web platform so authors can have ideas of what things are likely to be fast or slow, and what types of changes they can experiment with to improve the performance of their Web pages.
Optimizations can and do change
<script> div.setAttribute("data-rating", "excellent"); </script>
Browsers can check whether there are selectors that care about this attribute, and as a result not even compute style.
<script> div.setAttribute("data-rating", "excellent"); </script> <style> #list div[data-rating="excellent"] { background: yellow; color: black; } </style>
Now there are selectors, so we have to rerun selector matching. But
if the div isn't inside an element with id="list"
, nothing
changed.
<script> div.setAttribute("data-rating", "excellent"); </script> <style> div[data-rating="excellent"] { background: yellow; color: black; } </style>
Now the rerunning of selector matching actually makes a new rule match that didn't before.
This is how one browser optimizes today. It might change.
OK, so new rules matched? Let's figure out what properties changed.
display position float (from/to 'none') transform (from/to 'none') column-* counter-* quotes
width height font-* margin-* padding-* border-*-width letter-spacing word-spacing line-height
color background-* border-*-color z-index
Or maybe nothing changed:
p { background: yellow } p:hover { background: yellow }
transform cursor
Authors might change the same element twice:
element.style.position = "absolute"; element.style.overflow = "auto";
Authors might make changes where the work needed to handle one subsumes the work for the other:
element.style.backgroundColor = "blue"; element.parentNode.style.opacity = "0.8";
Browsers don't actually process the changes until:
getComputedStyle(element, "").color
(Maybe Gecko-specific; might only flush style)
getComputedStyle(element, "").width element.offsetTop
DO NOT DO THIS:
for (var i = 0; i < n; ++i) { var photo = document.getElementById("photo" + i); var label = document.getElementById("label" + i); label.style.top = photo.offsetHeight + "px"; }
These can sometimes be hidden in frameworks.
<script> /* likely Gecko-specific */ function flush_frames(elt) { getComputedStyle(elt, "").color; } var start = Date.now(); for (var i = 0; i < 10000; ++i) { test_elt.style.display = "none"; flush_frames(test_elt); test_elt.style.display = ""; flush_frames(test_elt); } var time = (Date.now() - start); </script>
<script> function flush_layout(elt) { elt.offsetTop; } var start = Date.now(); for (var i = 0; i < 10000; ++i) { test_elt.style.fontSize = "1px"; /* or width */ flush_frames(test_elt); test_elt.style.fontSize = ""; /* or width */ flush_frames(test_elt); } var time = (Date.now() - start); </script>