The Speed of Browser Rendering: Element inline styles vs
classes
We had an interesting issue while supporting an application
here at my client. We had a list of elements that we needed to filter based on
text inputs. The way the code worked it was using jQuery to take up the
collection and iterate through it based on the filter. It would then show or
hide the element based on the filter criteria. The problem was that the entire
process was slow and the business users were starting to find it burdensome.
Why was it slow? We spent several hours examining the legacy
code to understand exactly what it was doing and why. The project was
constrained to using jQuery to accomplish many of its UI tasks. Further, the
original writer of the code seemed to not think much of classes because they
were using inline element styles on all the elements.
We were unsure why the code did not perform quickly, but as
an exercise in best practices we replaced the inline element style with a class
(which we quickly defined in a style tag in the HTML). Immediately, the code
started to perform five times better. So, it seems that simply switching to a
class made the difference – but why?
The answer is that the browser has two separate pipelines
for HTML and CSS which are compiled together and sent to the browser’s Rendering
engine:
See the performance
issue for yourself, check out this benchmark: https://jsperf.com/inline-style-vs-css-class/2 (credit to Sergey Ermakovich )
So how are inline element styles handled in this process?
Per https://www.html5rocks.com/tutorials/internals/howbrowserswork/#style
, it turns out that inline styles are eventually translated into CSS rules for
the element upon which it sits. This means that for JavaScript processes that
are dynamically composing or changing large lists of elements each individual
element has its own style rule for the browser’s rendering engine to consider.
This, in effect, meant that there were hundreds of style
rules being created and changed for our application. Using a CSS class
corrected this problem because it reduced the style rules from hundreds to one.
Also, the browser can cache the CSS class for the benefit of the rendering
engine.
Furthermore, the CSS style rule that element inline styles
are eventually created into are one of the slowest types of CSS rules
available. The inline style results in an extremely specific ‘Descendent’
selector. This type of selector is slow because CSS is read from right to left
by the browser. So for example if we had this selector:
html
body ul li a {}
Then the browser
would first find all the <a> tags in the document, then it would find all
of the <a> tags with a <li> parent and so on until the specific
elements that match the criteria are resolved into a set and the rendering
engine can apply the styling required. (reference https://css-tricks.com/efficiently-rendering-css/ )
Finally, the Google
reference guide warns us that inline styles on HTML elements are blocked by
default with Content Security Policy.
But why should the CSP block inline styles? CSP doesn’t give
us an explanation – but I found one for you:
Before you even click, if you were thinking ‘I bet IE…’ the
answer is ‘yes’.
So, element inline styles – simply put, you probably should
not use them. If you do use them then be aware of the risks: they are slow and
they are a potential security problem.

No comments:
Post a Comment