Web browsers are more or less scriptable rendering engines. These engines usually render text and images but sometimes videos or similar medias too. The rendering process starts when browser receives HTML or markup. Let us look at them step wise
- Browser received HTML.
- Parses HTML.
- Constructs a DOM tree, root of this tree is html tag. with branches like body and sub branches like div or p or a.
- By this time browser has also received CSS(hopefully 🙂 and parses it. Stylesheets have “cascading” effect. All this start as
- Browser default styles.
- External styles contained in style sheets.
- Imported styles in @import style sheets.
- Inline styles in <style> tag.
- Finally the style defined in style attribute of an element.
- Now browser has CSS and markup and constructs a render tree. Render tree has everything that must be rendered on to the page. Now, until and unless there are hidden elements, render tree will have almost all the visible elements. Tags like <head>, <script> and similar other tags are not included. Every other visible element will be in render tree.
- Now as browser has a render tree result of the above “flow“, it will “paint” this tree.
- But things do not stop here, browser calculates everything again to match up the viewport and a “reflow” occurs. This can be seen demonstrated. Delay the CSS arrival by some time and you can see a page loading without style and then when CSS arrives everything is “repaint-ed“.
- All the above are very expensive operations. But any change in page can trigger these. Resizing window, animations, adding or removing elements in the page trigger reflows and repaints.
For better performance avoid reflowing and repainting the page. But that’s not possible in case of dynamic app world of today. But there are some ways to make these repaints and reflows fast. Don’t do Y.one(elem).setStyle(styleattribute, value)/$(elem).css(styleattribute, value). Instead simply change the class. Don’t do following in sequence
- Change the font color
- Change the font size
- Change the font width
Instead create a class with all of the above and replace it. Every step will ask browser to do reflow and repaint. Better, perform the steps in a “batch” in background using JS and then replace the block with new node you created using JS. Reflow and repaints affect the performance of a page in same way slow network or a bad JS code will do.