Front-end performance optimization-CSS performance optimization

This article introduces some CSS performance optimization schemes.

One, inline key CSS of the first screen

The approximate process of rendering:

  • Load HTML resources
  • Parse HTML
  • Load CSS resources and build DOM tree at the same time
  • Parse CSS and render the DOM tree at the same time

When the CSS file is too large, it will stay at step 3. When the Internet speed is slow, there is often no style when opening the website.

So we need to load part of the CSS (the CSS used for the first screen) first, and other CSS with a lower priority will be loaded asynchronously.

Inlining the key CSS required to render above-the-fold content into the HTML allows the CSS to be downloaded more quickly. It can be rendered after the HTML download is complete, and the page rendering time is advanced, thereby shortening the first screen rendering time; the
remaining CSS uses external CSS files, and downloads them after the HTML document is downloaded. This enables caches, but in addition to loading them asynchronously.

Disadvantages : CSS after inlining will not be cached and will be re-downloaded every time.

Second, load CSS asynchronously

CSS will block rendering. The browser will not render any processed content until the CSS file request, download, and parsing are completed. Sometimes, this blocking is necessary because we don't want the browser to start rendering the page before the required CSS is loaded. Then after the key CSS of the first screen is inlined, the blocking rendering of the remaining CSS content is not necessary. You can use external CSS and load it asynchronously.

Several ways to load asynchronously

1.js dynamically creates the style sheet link element and inserts it into the DOM.

// 创建link标签
const myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// 插入到header的最后位置
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );

2. Set the media attribute

Set the media attribute of the link element to a media type (or media query) that does not match the user's browser, such as media="print", or even a completely non-existent type media="noexist". For the browser, if the style sheet is not suitable for the current media type, its priority will be lowered, and it will be downloaded without blocking the page rendering.

<link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">

Of course, this is just to implement the asynchronous loading of CSS. Don't forget to set the value of media to screen or all after the file is loaded, so that the browser can start to parse the CSS.

3. Set the rel attribute

Marking the link element as an alternative style sheet through the rel attribute can also achieve asynchronous loading by the browser. Also don't forget to change the rel back after loading is complete.

<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">

4. rel=“preload”

<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">

Note that as is required. Ignoring the as attribute or the wrong as attribute will make preload equal to an XHR request. The browser does not know what content is loaded, so the priority of loading such resources will be very low.

Three, file compression

The size of the file will directly affect the loading speed of the browser. The current builds of webpack, gulp/grunt, rollup, etc. also support CSS compression. The compressed file can be significantly reduced, which can greatly reduce the loading time of the browser.

Such as: extract-text-webpack-plugin

Fourth, remove useless CSS

Although file compression can reduce file size, css file compression usually only removes useless spaces, which limits the compression ratio of css files. If the compressed file still exceeds the expected size, you can try to find and delete the useless css in the code.
Under normal circumstances, there will be two kinds of useless CSS codes:

  • Duplicate code in different elements or other situations,
  • There is no effective CSS code in the entire page

Clever use of css inheritance mechanism, if the parent node is defined, the child node does not need to be defined.

Five, use selectors selectively

The matching of CSS selectors is carried out from right to left. This strategy leads to differences in performance between different types of selectors.

More selectors in CSS will not match, so when considering performance issues, what needs to be considered is how to improve efficiency when selectors do not match. Matching from right to left is for this purpose.

Compared to #abc, obviously when using #a .bc, the browser takes more time to generate the render-tree. Because the latter needs to find all c elements in the DOM, and then filter out the ancestor elements that are not .b, and finally filter out the ancestors of .b that are not #a. The more levels of nesting, the longer it will take.

  1. Don't use selectors that are too nested or too complex.
  2. Wildcards and attribute selectors are the least efficient and need to match the most elements, so avoid using them as much as possible.
  3. Do not use class selectors and ID selectors to decorate element tags, such as h3#markdown-content
    (ID is originally unique and has a large permission value. Nesting is a waste of performance.)

Sixth, reduce the use of expensive attributes

When the browser draws the screen, all the properties that need to be manipulated or calculated by the browser are relatively expensive. When the page is redrawn, they will reduce the rendering performance of the browser. Minimize the use of expensive attributes, such as box-shadow/border-radius/filter/transparency/:nth-child, etc.

7. Optimize rearrangement and redraw

1. Reduce rearrangement

Rearrangement will cause the browser to recalculate the entire document and rebuild the rendering tree, which will reduce the browser's rendering speed.

Operations that will cause rearrangement:

  • Add or remove visible DOM elements
  • Element position change
  • Element size change
  • The content of the element changes (for example: a text is replaced by another image of a different size)
  • Page rendering initialization (this cannot be avoided)
  • Browser window size changed
  • CSS pseudo-class activation

Common rearrangement elements:

  1. Size related width, height, padding, margin, border-width, border, min-height
  2. Layout related display, top, position, float, left, right, bottom
  3. Font-related font-size, text-align, font-weight, font-family, line-height, white-space, vertical-align
  4. Hide related overflow, overflow-x, overflow-y

Use the following steps to avoid most reflows on the page:

  • Use absolute positions to position the animated elements on the page to get them out of the document flow
  • Let the elements move. When it expands, it will temporarily cover part of the page. But this is only the redrawing process of a small area of ​​the page, and it will not re-arrange and redraw most of the content of the page.
  • When the animation ends, the positioning is restored, so that the other elements of the document will only be moved down once
  • When using Flex, the rearrangement is faster than when using inline-block and float, so Flex can be given priority in layout.

2. Avoid unnecessary redrawing

During the use of the website, redrawing is unavoidable. However, the browser has optimized this, it will combine multiple reflow and redraw operations into one execution. However, we still need to avoid unnecessary redrawing, such as the hover event triggered when the page is scrolled, and the hover event can be disabled when scrolling, so that the page will be smoother when scrolling.

When the appearance of an element (such as color, background, visibility, etc.) changes, it will trigger a redraw.

8. Make the elements and their contents as independent as possible from the rest of the document tree

The contain attribute allows us to specify a specific DOM element and its child elements so that they can be independent of the entire DOM tree structure. The purpose is to enable the browser to have the ability to redraw and rearrange only part of the elements without having to target the entire page each time. That is, allowing the browser to recalculate the layout, style, painting, size or any combination of them for a limited area of ​​the DOM instead of the entire page.

In actual use, we can specify how the element is independent of the document tree by setting one of the following five values ​​to contain:

  • layout: This value means that the internal layout of the element is not affected by any external influences, and the element and its content will not affect the upper level; the descendants of the container should not cause the layout of the element outside the container to change, and vice versa
  • paint: This value indicates that the children of the element cannot be displayed outside the scope of the element, and the element will not have any content overflow (or even if it overflows, it will not be displayed); the content of the container will never be drawn beyond the container Size, if the container is blurred, then the content will not be drawn at all
  • size: This value indicates that the size of the element box is independent of its content, that is to say, its child elements will be ignored when calculating the size of the element box; when its content changes, the container should not cause the position on the page to move
  • content: This value is shorthand for contain: layout paint
  • strict: This value is shorthand for contain: layout paint size

Nine, avoid using @import

Using @import to introduce css will affect the browser's parallel download. The css file referenced by @import is downloaded only when the css file that refers to it is downloaded. After parsing, the browser will know that there is another css to download, then download it, and then start parsing after downloading, constructing the render tree, etc. A series of operations, which makes browsers unable to download in parallel, using @import in external css files will cause additional delays when the page loads.
It is better to use the link tag.

Ten, turn on GPU rendering animation

The browser is optimized for handling CSS animations and animation properties that do not trigger reflow well (and therefore cause drawing).

In order to improve performance, the animated node can be moved from the main thread to the GPU. The properties that will cause the composition include 3D transforms (transform: translateZ(), rotate3d(), etc.), animation, transform and opacity, position: fixed, will-change, and filter. Some elements, for example, and, are also located on their respective layers. When promoting elements to layers (also called compositing), the animation transition properties will be done in the GPU, thereby improving performance, especially on mobile devices.

Eleven, merge css files

If the page loads 10 css files, each file is 1k, then it will be slower than just loading a 100k css file.

Reference: https://blog.csdn.net/weixin_38015898/article/details/107215259

For more optimization solutions, see: https://juejin.cn/post/6942661408181977118

Link to this article: https://blog.csdn.net/qq_39903567/article/details/115262201

Guess you like

Origin blog.csdn.net/qq_39903567/article/details/115262201