Home > Article > Web Front-end > 8 CSS performance optimization tips worth knowing
This article will introduce you to 8 tips for CSS performance optimization. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.
We all know that performance is crucial for a website. As an important part of page rendering and content presentation, CSS affects the user’s first experience of the entire website. Therefore, the performance optimization associated with it cannot be ignored.
We often only consider performance optimization when the project is completed. It is often postponed to the end of the project, or even when serious performance problems are exposed. I believe most people have a deep understanding of this. .
The author believes that in order to avoid this situation, we must first pay attention to the work related to performance optimization and integrate it into the entire product design and development. Secondly, it is to understand the performance-related content and naturally perform performance optimization during the project development process. Finally, and most importantly, start optimizing now.
It is recommended that you read the article "Hey, I'll give you a Web Performance Optimization Map" 1 previously recommended by Qiwu Weekly, which can help you form an understanding of what needs to be done and what issues need to be considered for performance optimization. The overall concept
.
This article will introduce in detail the techniques related to CSS performance optimization. The author divides them into two categories: practical and suggested, with a total of 8 tips. Practical techniques can be quickly applied in projects and can greatly improve performance. They are also often used by the author. It is recommended that everyone practice them in projects as soon as possible. Among the suggested techniques, some may not have a significant impact on performance, and some may not be used by everyone, so I will not focus on them. Readers can learn about them based on their own situations. (Learning video sharing: css video tutorial)
Before the official start, everyone needs to have some understanding of the working principle of the browser 2. Friends who need it can briefly understand it first.
Let’s start with the four practical optimization techniques, starting with the key CSS on the first screen.
There is an important indicator in performance optimization-First effective drawing( First Meaningful Paint (FMP for short) refers to the time when the primary content of the page appears on the screen. This indicator affects the time users need to wait before seeing the page, and inline critical CSS (Critical CSS, which can be called critical CSS on the first screen) can reduce this time.
Everyone should be accustomed to referencing external CSS files through the link tag. But what you need to know is that inlining the CSS directly into the HTML document makes the CSS download faster. When using external CSS files, you need to know the CSS files to be referenced after the HTML document is downloaded, and then download them. Therefore, inline CSS can make the browser start rendering the page earlier , because it can be rendered after the HTML download is completed.
Since inline CSS can advance the start time of page rendering, can all CSS be inlined? The answer is obviously no, this method is not suitable for inlining larger CSS files. Because there is a limit on the initial congestion window 3 (TCP related concept, usually 14.6kB, compressed size), if the file after inline CSS exceeds this limit, the system will need to make more rounds between the server and the browser. Round trip, this does not advance the page rendering time. Therefore, we should only inline the critical CSS required to render above-the-fold content into the HTML.
Now that we know that inline key CSS on the first screen can optimize performance, the next step is how to determine the key CSS on the first screen. Obviously, we don’t need to manually determine what content is above the fold critical CSS. There is a project on Github called Critical CSS4, which can extract the key styles belonging to the first screen. You can take a look at the project and use it with your own build tools. Of course, in order to ensure accuracy, it is best for you to personally confirm whether the extracted content is missing.
However, there is a disadvantage of inline CSS. The CSS after inline will not be cached and will be re-downloaded every time. However, as mentioned above, if we control the inline file size within 14.6kb, this does not seem to be a big problem.
As above, we have introduced why we need to inline key CSS and how to inline it. So how do we deal with the remaining CSS? It is recommended to use external CSS to introduce the remaining CSS, which enables caching, in addition to loading them 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, blocking rendering of the remaining CSS content is not necessary. External CSS can be used and loaded asynchronously.
So how to implement asynchronous loading of CSS? There are four ways to implement asynchronous loading of CSS
by the browser.
The first way is to use JavaScript to dynamically create a stylesheet link element and insert 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 );
The second way is to set the media attribute of the link element to a media type (or media query) that the user's browser does not match, 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 page rendering.
Of course, this is only to achieve 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 starts to parse the CSS.
<link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">
Similar to the second method, we can also mark the link element as an alternate optional style sheet through the rel attribute, which can also achieve asynchronous loading by the browser. Also don’t forget to change rel back after loading is complete.
<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">
The above three methods are relatively old. Now, the web standard rel="preload"5 points out how to load resources asynchronously, including CSS-like resources.
<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 equivalent to an XHR request. The browser does not know what content is being loaded, so the loading priority of such resources will be very low. The optional values of as can refer to the above standard documents.
It seems that the usage of rel="preload" is no different from the above two. They both change certain attributes so that the browser loads the CSS file asynchronously but does not parse it until the loading is completed and the modifications are restored. Then start parsing.
But there is actually a very important difference between them, that is, using preload can start loading CSS earlier than using the unmatched media method. Therefore, although the support for this standard is not yet complete, it is still recommended to use this method as a priority.
This standard is now a candidate standard, and I believe browsers will gradually support it. The support of each browser is shown in the figure below.
One of the easiest and most commonly used methods to think of when optimizing performance is file compression. This solution is often effective.
The size of the file will directly affect the loading speed of the browser, which is especially obvious when the network is poor. I believe that everyone is already accustomed to compressing CSS. Today's construction tools, such as webpack, gulp/grunt, rollup, etc., also support CSS compression function. The compressed file can be significantly reduced, which can greatly reduce the browser's loading time.
Although file compression can reduce file size. However, CSS file compression usually only removes useless spaces, which limits the compression ratio of CSS files. Are there other ways to streamline CSS? The answer is obviously yes, if the compressed file still exceeds the expected size, we can try to find and remove the useless CSS in the code.
Generally, there are two types of useless CSS code: one is repeated code in different elements or other situations, and the other is CSS code that does not take effect in the entire page. For the former, when writing code, we should extract public classes as much as possible to reduce duplication. For the latter, in the process of code maintenance by different developers, there will always be CSS code that is no longer used. Of course, this problem may also occur when one person writes it. These useless CSS codes will not only increase the browser's download volume, but also increase the browser's parsing time, which is a huge drain on performance. So we need to find and remove these useless codes.
Of course, it is very inefficient to manually delete these useless CSS. We can do this with the help of the Uncss7 library. Uncss can be used to remove useless CSS from style sheets and supports multi-file and JavaScript-injected CSS.
We have already talked about the four practical optimization techniques. Now we will introduce the four suggested techniques.
Most friends should know that CSS selector matching is performed from right to left. This strategy leads to There are also performance differences between different kinds of selectors. Compared with #markdown-content-h3, it obviously takes more time for the browser to generate the render-tree when using #markdown .content h3. Because the latter needs to first find all h3 elements in the DOM, then filter out the ancestor elements that are not .content, and finally filter out the ancestors of .content that are not #markdown. Just imagine, if there are more nesting levels and more elements on the page, the time cost of matching will naturally be higher.
However, modern browsers have made a lot of optimizations in this aspect, and the performance difference between different selectors is not obvious, or even very small. In addition, the performance of different selectors in different browsers is not completely uniform, and it is impossible to take into account every browser when writing CSS. In view of these two reasons, when we use the selector, we only need to remember the following points, and the rest can be completely based on preference.
Keep it simple and don’t use overly complex selectors that are nested too much.
Wildcards and attribute selectors are the least efficient and require the most matching elements, so try to avoid using them.
Do not use class selectors and ID selectors to modify element tags, such as h3#markdown-content. This is unnecessary and will reduce efficiency.
Don’t give up readability and maintainability in pursuit of speed.
If you still have questions about the above points, the author recommends that you choose one of the following CSS methodologies (BEM9, OOCSS10, SUIT11, SMACSS12, ITCSS13, Enduring CSS14, etc.) as CSS writing specifications. Using a unified methodology can help everyone form a unified style, reduce naming conflicts, and avoid the above problems. In short, there are many benefits. If you haven't used it yet, start using it quickly.
Tips: Why do CSS selectors match from right to left?
More selectors in CSS will not match, so when considering performance issues, what needs to be considered is how to improve efficiency when the selectors do not match. Matching from right to left is to achieve this purpose. This strategy can make the CSS selector more efficient when it does not match. Thinking about it this way, it makes sense to consume more performance during matching.
When the browser draws the screen, all properties that require the browser to operate or calculate are relatively needed Cost more. When page redraws occur, they reduce the browser's rendering performance. So when writing CSS, we should try to reduce the use of expensive properties, such as box-shadow/border-radius/filter/transparency/:nth-child, etc.
Of course, this does not mean that everyone should not use these attributes, because these should be attributes we often use. The reason why I mention this is to let everyone have an understanding of this. When there are two options to choose from, you can give priority to the option with no expensive attributes or fewer expensive attributes. If you make this choice every time, the performance of the website will be improved unconsciously.
During the use of the website, certain operations will cause style changes, and the browser needs to detect these changes. And re-render, some of which cost more performance. We all know that when the FPS is 60, users will feel smooth when using the website. This means that we need to complete all operations related to each rendering within 16.67ms, so we must try to minimize more expensive operations.
3.1 Reduce reflow
Reflow will cause the browser to recalculate the entire document and rebuild the rendering tree. This process will reduce the browser's rendering speed. As shown below, there are many operations that trigger rescheduling, and we should avoid triggering these operations frequently.
Change font-size and font-family
Change the inner and outer margins of the element
Change the CSS class through JS
Get the position-related attributes of the DOM element through JS (such as width/height/left, etc.)
CSS pseudo-class Activate
Scroll the scroll bar or change the window size
In addition, we can also query which properties will trigger reflow and redraw through CSS Trigger15 .
It is worth mentioning that some CSS properties have better reflow performance. For example, when using Flex, reflow is faster than when using inline-block and float, so Flex can be given priority during layout.
3.2 Avoid unnecessary redrawing
When the appearance of an element (such as color, background, visibility and other attributes) changes, redrawing will be triggered. During the use of the website, redrawing is inevitable. However, the browser has optimized this and merges 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 scrolling. You can disable the hover event when scrolling, so that the page will scroll more smoothly.
In addition, we write more and more animation-related codes in CSS, and we are accustomed to using animation to improve user experience. When we write animations, we should also refer to the above content to reduce the triggering of redrawing and rearrangement. In addition, we can also improve animation performance through hardware acceleration 16 and will-change17. This article will not introduce this in detail. Interested friends can click on the link to view it.
Finally, it should be noted that the user's device may not be as good as imagined, at least not as good as our development machine. We can use Chrome's developer tools to slow down the CPU, and then conduct related tests
If you need to access it on the mobile side, it is best to set the speed limit lower, because the performance of the mobile side is often worse.
Finally, don’t use @import to introduce CSS. I believe everyone rarely uses it.
It is not recommended to use @import mainly for the following two reasons.
First of all, using @import to introduce CSS will affect the browser's parallel downloading. The CSS file referenced using @import will only know that there is another CSS file that needs to be downloaded and parsed after the CSS file that references it is downloaded. Then it will download it, and then start parsing, building render tree, etc. after downloading. A series of operations. This results in the browser being unable to download the required style files in parallel.
Secondly, multiple @imports will cause the download order to be disordered. In IE, @import will cause the download order of resource files to be disrupted, that is, the js files listed after @import are downloaded before @import, and disrupt or even destroy the parallel download of @import itself.
So don’t use this method, just use the link tag.
For more programming-related knowledge, please visit: Programming Teaching! !
The above is the detailed content of 8 CSS performance optimization tips worth knowing. For more information, please follow other related articles on the PHP Chinese website!