Home  >  Article  >  Web Front-end  >  Why should every front-end developer understand page rendering? _html/css_WEB-ITnose

Why should every front-end developer understand page rendering? _html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 11:51:18886browse

Rendering should be optimized from the very beginning when the page layout is defined. Styles and scripts play a very important role in page rendering. Professionals know a few tricks to avoid some performance issues.

This article will not delve into the technical details of the browser, but rather provide some general principles. Different browser engines work differently, which makes learning a specific browser more complicated.

How does the browser render a page?

Let’s start with the general process of the browser rendering the page:

  • The DOM (Document Object Model) is formed from the HTML received from the server.
  • Styles are loaded and parsed to form CSSOM (CSS Object Model).
  • Following the DOM and CSSOM, a rendering tree is created. This rendering tree is a collection of rendered objects (Webkit calls them "renderer" and "render object" respectively, while in the Gecko engine it is called "frame" ). Except for invisible elements (such as the head tag and some elements with the display:none attribute), the render tree maps the structure of the DOM. In the rendering tree, each text string is treated as an independent renderer. Each render object contains a corresponding DOM object (or a text block) with calculated styles. In other words, the render tree describes the visual representation of the DOM.
  • For each rendered element, its coordinates are calculated, which is called "layout". Browsers lay out all elements using a "flow method" that only needs to be processed once (tables need to be processed multiple times).
  • Finally, the layout is displayed in the browser window. This process is called "painting".
  • Redraw

    When some styles that do not require changing positioning are modified on the page (such as background-color, border-color, visibility), the browser Only the new style will be redrawn to the element (this is called a "redraw" or "redefinition of styles").

    Reflow

    Reflow (or "relayout") occurs when changes on the page affect the content, structure, or positioning of elements in the document. Rearrangement is usually triggered by the following changes:

  • DOM operations (such as adding, deleting, changing elements, or changing the order of elements).
  • Content changes, including changes to text in the Form.
  • Calculate or change CSS properties.
  • Add or delete a style sheet.
  • Change the "class" attribute.
  • Browser window operations (resize, scroll window).
  • Activate pseudo-class (such as: hover state).
  • How does the browser optimize rendering?

    Browsers do their best to limit the reflow process to only the area of ​​the element that has changed. For example, changing the size of an element with a position of absolue or fixed only affects itself and its descendants, while doing the same to an element with a position of static will cause the rearrangement of all elements behind it.

    Another optimization is that when running a piece of Jjavascript code, the browser will cache some modifications, and then execute these modifications at once when the code is executed. For example, this code triggers a repaint and a reflow:

    1. var $body = $('body');
    2. $body.css('padding', '1px'); // Reflow, redraw
    3. $body.css('color', 'red'); // Redraw
    4. $body.css('margin', '2px'); // Reflow, redraw
    5. // Actually only one reflow and redraw is performed.

    As mentioned above, accessing the attributes of an element will force a rearrangement. If we add a line of code to read the element attributes to the above code, this situation will occur:

    1. var $body = $('body') ;
    2. $body.css('padding', '1px');
    3. $body.css('padding'); // Here the attributes of the element are read once and forced once Rearrangement will occur.
    4. $body.css('color', 'red');
    5. $body.css('margin', '2px');

    The result of the above code is that two rearrangements are performed. Therefore, to improve performance, you should organize the code that reads element attributes together (see the code on JSBin for detailed examples).

    There is a situation where a forced reordering must be triggered. For example: change the same attribute of an element twice (such as margin-left), initially set it to 100px without animation, and then change the value to 50px through animation. You can see examples for details. Of course, I will go into more details here.

    We start with a CSS class with transition:

    1. .has-transition {
    2. -webkit-transition: margin-left 1s ease-out;
    3. -moz-transition: margin-left 1s ease-out;
    4. -o-transition: margin-left 1s ease-out;
    5. transition: margin-left 1s ease-out;
    6. }

    Then implement:

    1. //Our elements have the "has-transition" attribute by default
    2. var $targetElem = $('#targetElemId');
    3. //Delete the class containing transition
    4. $targetElem.removeClass('has-transition');
    5. // When the class containing the transition is gone, change the element attributes
    6. $targetElem.css('margin-left', 100);
    7. // Then add the class containing the transition back
    8. $targetElem.addClass('has-transition');
    9. / / Change element attributes
    10. $targetElem.css('margin-left', 50);
    The above implementation does not work as expected. All modifications are cached by the browser and will only be executed at the end of the above code. What we need is a forced rearrangement, which we can achieve by making the following modifications:

    1. //Delete the class containing transition
    2. $ (this).removeClass('has-transition');
    3. // Change element attributes
    4. $(this).css('margin-left', 100 );
    5. //Trigger a forced reordering so that the changed class or attribute can be executed immediately.
    6. $(this)[0].offsetHeight; // offsetHeight is just an example, other properties can also work.
    7. // Add the class containing the transition back
    8. $(this).addClass('has-transition');
    9. //Change element attributes
    10. $(this).css('margin-left', 50);

    Now this code It worked as we expected.

    Actual optimization suggestions

    Putting together some useful information, I recommend the following:

  • Create legal HTML and CSS, don’t forget In order to specify the file encoding, the Style should be written in the head tag, and the script tag should be loaded at the end of the body tag.
  • Try to simplify and optimize CSS selectors (this optimization point is ignored by most developers using CSS preprocessors). Keep the number of nesting levels to a minimum. Here is the performance ranking of CSS selectors (starting with fastest):
  • ID selector: #id
  • class selector: .class
  • Tag: div
  • Adjacent sibling elements: a i
  • Parent element selector: ul > li
  • Wildcard selector: *
  • Pseudo class and pseudo element: a:hover, you should remember that browsers process selectors from right to left, which is why the rightmost selector is faster?? #id or .class.
    1. div * {...} // bad
    2. .list li {...} // bad
    3. .list-item {...} // good
    4. #list .list-item {...} // good
  • In your script, reduce DOM manipulation as much as possible. Cache everything, including properties and objects (if it can be reused). When performing complex operations, it is best to operate on an "offline" element (an "offline" element means an element that is separate from the DOM object and only exists in memory), and then insert this element into the DOM.
  • If you use jQuery, follow jQuery selector best practices
  • To change the style of an element, modifying the "class" attribute is one of the most efficient ways. The deeper you go in the DOM tree to change, the more efficient this becomes (it also helps separate presentation from logic).
  • As much as possible, only animate elements whose position is absolute or fix.
  • It would be a good idea to disable some complex :hover animations when scrolling (e.g. add a no-hover class to the body tag) There is an article on this topic.
  • Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn