Browser Parts | Browsers
Standards Based Development
Browser Action Overview While Rendering a Document
- The dom is formed from the html that is recieved from a server
- Styles are then loaded and parsed, forming the cssom (css Object Model)
- Atop the dom and cssom, a rendering tree is created; a rendering tree is a set of objects to be rendered; WebKit calls each of those a "renderer" or a "render object", while in Gecko it is a "frame". Render tree reflects the dom structure except for invisible elements (like
head, also elements withdisplay:noneset. Each text string is represented in the rendering tree as a separate renderer. Each of the rendering object contains its corresponding dom object (or a text block) plus the calculated styles. In other words, the render tree describes the visual representation of the dom - Each render tree's coordinates are calculated, which is called layout. Browser use a flow method which only required one pass to layout all the elements (tables require more than one pass)
- Finally, all of this is actually displayed in the a browser window, a process known as painting>
- dom manipulation (element addition, deletion, altering, or changing element order)
- Contents changes, including text changes in form fields
- Calculation or altering of css Properites
- Adding or Removing Style Sheets
- Changing the
class=""Attribute - Browser Window Manipulation (resizing, scrolling, etc.)
- Pseudo-class Activation (
hover - Create valid html, and css, do not forget to specify the document encoding. Styles should be included into
head, andscripts should be appended to the end of thebodyelement. - Simplify and Optimize css Selectors - Note: this is almost universally ignored by developers who mostly use css Preprocessors. Keep nesting levels at a minimum.
This is How css Selectors Rank According to Their Performance; starting from the fastest:
- Identificator:
id="" - Class:
class="" - Element:
div - Adjacent Sibling Selector:
a + i - Parent Selector:
ul > li - Universal Selector:
* - Attribute Selector:
input[type="text"] - Pseudo-classes and Pseudo-elements (
:hover) Remember that browsers process selectors from right to left, which is why the rightmost selector should be the fastest one - either#id, or.class:
div *{} // bad .list li{} // bad .list-item{} // good #list .list-item{] // good- Minimize dom Manipulation in your scripts, whenever possible. Cache everything, including properties, and objects (should you be reusing them). It is optimal to work with an "offline" element when performing complicated manipulations (an "offline" element is one that is disconnected from the dom and only stored in memory), and append it to the dom afterwards
- Note: follow jQuery selectors best practices when selecting elements via jQuery
- When Changing an Element's styles, modify the
class=""attribute is one of the most important ways. The deeper into the dom tree you perform this change, the better (also because this helps decouple logics from presentation). - Only apply animation to
absolutely/fixed positionelements - Disable complicated
:hoveranimations while scrolling (e.g., by adding an extra.no-hoverclass to thebodyelement.
More Reading in the Two Links Below: UPON READING, TAKE NOTES!
How Browsers Work
The Timeline Tab in Chrome's Developer Tools offers information regarding repaint/reflow/style recalculations in regards to performance; you can export Timeline tab data as json.
Browser Paints
css Properties that can affect browser painting during page rendering:
position:fixedbackground-position: fixed
- Identificator:
border-radiusbackground-sizebox-shadowgradient- Profiling css for fun and profit. Optimization notes
- Profiling Long Paint Times With DevTools' Continuous Painting Mode
- Rending, Repaint, Reflow, Relayout, and Restyle
- Mozilla: notes on reflow
- Google tech talk on Layout Engine Internals for Web Developers by David Baron of Mozilla
- WebKit: rendering basics - 6-part series of posts
- repaints and reflows is a part of an article on efficient JavaScript by dev.opera squad
- Dynatrace: IE rendering behavior
When users interact with a page, or scripts modify it, some of the aforementioned operations have to be repeated, as the underlying page structure changes.
Repaint
When element styles are changed that do not affect the element's position on a page (like background-color, border-color, visibility), the browser just repaints the element again with the new styles applied (note: that means a "repaint", or "restyle" is happening.
Reflow
When changing element styles affect document contents or structure, or element position, a reflow (or relayout) happens.
Reflows and relayouts are typically triggered by:
Reflow is the process by which the geometry of the layout engine's formatting objects are computed. html formatting objects are called frames: a frame corresponds to the geometric framework for (roughly) a single element in the content modle; the frames are arranged into a hierarchy that parallels the containment hierarchy in the content model. A frame is rectangular, with width, height, and an offset from the parent frame that contains it.
References and Resources
How Browser Optimize Rendering
Browsers do their best to restrict repaint%reflow to the areas covering the changed elements only.
Browsers have many optimization techniques and options: one they use routinely: while running pieces of JavaScript code, the Browser will cache the changes, and apply them to a single pass after the code was run. So for example, the piece of code below will only trigger one reflow and one repaint:
var $body = $("body");
$body.css("padding", "1px"); // reflow, repaint
$body.css('color', 'red'); // repaint
$body.css('margin', '2px'); // reflow, repaint
// only 1 reflow and repaint will actually happen
As previously mentioned, accessing an element property triggers a forced reflow; This will happen if we add an extra line that reads an element property to the previous block:
var $body = $('body');
$body.css('padding', '1px');
$body.css('padding'); // reading a property, a forced reflow
$body.css('color', 'red');
$body.css('margin', '2px');
As a result, we get two reflows instead of one, and because of this, you should group reading elemental properties together to optimize performance. You can view a more detailed example here on jsbin
Triggering a Forced Reflow
At times you'll have to trigger a forced reflow, perhaps you need to apply the same property (margin-left) to the same element twice. Initially, it is set to 100px without animation, and then it has to be animated with transition to a value of 50px. You can study this example via jsBin, but here's the details:
Start by creating an html class="" with a transition:
.has-transition {
-webkit-transition: margin-left 1s ease-out;
-moz-transition: margin-left 1s ease-out;
-o-transition: margin-left 1s ease-out;
transition: margin-left 1s ease-out;
}
We then proceed with the implementation:
// our element that has a "has-transition" class by default
var $targetElem = $('#targetElemId');
// remove the transition class
$targetElem.removeClass('has-transition');
// change the property expecting the transition to be off, as the class is not there
// anymore
$targetElem.css('margin-left', 100);
// put the transition class back
$targetElem.addClass('has-transition');
// change the property
$targetElem.css('margin-left', 50);
However, this implementation does not work as expected; the changes are cached and applied only at the end of the code block. What we need is a forced reflow, which we can achieve by making the following changes:
// remove the transition class
$(this).removeClass('has-transition');
// change the property
$(this).css('margin-left', 100);
// trigger a forced reflow, so that changes in a class/property get applied immediately
$(this)[0].offsetHeight; // an example, other properties would work, too
// put the transition class back
$(this).addClass('has-transition');
// change the property
$(this).css('margin-left', 50);
Then we continue to proceed with the implementation:
Note: this implementation does not work as expected; changes are cached and applied only at the end of the code block. A forced reflow is what is needed here, which we can achieve by making the following alterations:
Success! Now the code works as expected.
Optimization Summary
Things You May Not Have Known About html css