Webpage rendering - For Frontend Developers
Posted on May 4th, 2016
This is perhaps one of the most important topic for any frontend developer. Its also one of the common interview question. You fuck up on this, you lose the battle.
Why is this important ?
If you have built a complete website end-to-end, keeping all the best practices in mind but still your site is slow, you basically didnt pay much importance on how a browser renders your website. Also, you will never be able to understand the beauty of latest libraries like ReactJS.
Rendering has to be optimized from the very beginning, when the page layout is being defined, as styles and scripts play the crucial role in page rendering.
How Browsers Render ?
- After receiving the response from the server, the DOM (Document Object Model) is formed.
- Then the CSSOM (CSS Object Model) is formed after the styles are loaded and parsed.
- The DOM and CSSOM are combined into a “render tree” that captures all the visible DOM content (excluding <head> and elements that have
display:none;set) on the page, plus all the CSSOM style information for each node. In other words, the render tree describes the visual representation of a DOM.
- With the render tree in place, the browser proceeds to the “layout” stage, where for each element of render tree, its coordinates are calculated.
- The final stage is called Painting where the elements become visible on the browser.
Repaint and Reflow
A Repaint occurs when changes are made to an elements skin that changes visibility, but do not affect its layout. Examples of this include outline, visibility, or background color.
A Reflow computes the layout of the page. A reflow on an element recomputes the dimensions and position of the element, and it also triggers further reflows on that element’s children, ancestors and elements that appear after it in the DOM. Then it calls a final repaint. Reflowing is very expensive.
var $body = $('body'); //cache the body node $body.css('padding', '5px'); // reflow, repaint $body.css('color', 'green'); // repaint $body.css('margin', '10px'); // reflow, repaint
Some reflows may be more expensive than others. Think of the render tree - if you fiddle with a node way down the tree that is a direct descendant of the body, then you're probably not invalidating a lot of other nodes. But what about when you animate and expand a div at the top of the page which then pushes down the rest of the page - that sounds expensive.
Don't change individual styles, one by one. Best for sanity and maintainability is to change the class names not the styles.
var $ele = $("#element"); // bad $ele.css('left','10px'); $ele.css('top','10px'); // better $ele.addClass('newClass'); //this class should contain the appropritate styles
- In your scripts, minimize DOM manipulation whenever possible. Cache everything, including properties and objects (if they are to be reused). It's better to work with an "offline" element when performing complicated manipulations (an "offline" element is one that is disconnected from DOM and only stored in memory), and append it to DOM afterwards.
- If you use jQuery to select elements, follow jQuery selectors best practices.
- To change element's styles, modifying the "class" attribute is one of the most performant ways. The deeper in the DOM tree you perform this change, the better (also because this helps decouple logic from presentation).
- Animate only absolute/fixed positioned elements if you can.
- It is a good idea to disable complicated
:hoveranimations while scrolling (e.g. by adding an extra "no-hover" class to <body>).
I hope you find this article useful!