How to optimize CSS performance? The following article will introduce you to some CSS performance optimization tips. I hope it will be helpful to you!
With the development of the Internet, performance has become more and more important for websites. CSS, as an important part of page rendering and content presentation, affects users’ understanding of the website. First experience with the entire website. Therefore, we need to pay attention to performance optimization related to CSS. [Recommended learning: css video tutorial]
In the early stage of project development, we may have a variety of reasons (a large part of the reason is due to the project duration, and the product often delays the project launch time) , I don’t even listen to what you said about performance optimization), just write whatever you feel comfortable with. We often only consider performance optimization when the project is completed, and it is often postponed to the end of the project, or even when serious performance problems are exposed. Only then perform performance optimization.
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.
To optimize the performance of CSS, we first need to understand the rendering rules of CSS. CSS selectors are matched from right to left
Let’s take an example:
.nav h3 a{font-size: 14px;}复制代码
The rendering process is probably: first find all a
, and then search h3## along the parent element of
a #, and then search
.nav along
h3. If a node that meets the matching rules is found midway, it is added to the result set. If there is no match for the root element
html, the path will no longer be traversed and the search will be repeated starting from the next
a (as long as there are multiple rightmost nodes on the page that are
a).
Inline first screen critical CSS (Critical CSS) There is an important indicator in performance optimization-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.
First meaningful paint (First Meaningful Paint, referred to as FMP) refers to the time when the primary content of the page appears on the screen. This indicator affects the time that users need to wait before seeing the page, and Inline critical CSS on the first screen (that is, Critical CSS, which can be called critical CSS on the first screen) can reduce this time.
Many people like to reference externalCSS files through the
link tag. But what you need to know is that
inlining CSS directly into the HTML document can make 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.
(TCP related concepts, usually 14.6kB, compressed size), If the file after inlining CSS exceeds this limit, the system will need to make more round trips between the server and the browser, which will not advance the page rendering time. Therefore, we should
only inline the critical CSS required to render above-the-fold content into the HTML.
14.6kB Within this, it still plays a positive role in performance optimization. (Everything has advantages and disadvantages)
These browser interview questions, see See how many answers you can answer? )
will not block the parsing of
DOM, but will block
DOM The rendering of
will block
JS execution, but will not block the download of
JS files
CSS asynchronous loading method
The first method is to create dynamically
// 创建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 );
第二种方法是将link元素的media
属性设置为用户浏览器不匹配的媒体类型(或媒体查询)
对浏览器来说,如果样式表不适用于当前媒体类型,其优先级会被放低,会在不阻塞页面渲染的情况下再进行下载。在首屏文件加载完成之后,将media
的值设为screen
或all
,从而让浏览器开始解析CSS。
<link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">
第三种方法是通过rel
属性将link
元素标记为alternate
可选样式表
<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">
第四种方法是使用rel=preload
来异步加载CSS
<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
注意,as
是必须的。忽略as
属性,或者错误的as
属性会使preload
等同于XHR
请求,浏览器不知道加载的是什么内容,因此此类资源加载优先级会非常低。as
的可选值可以参考上述标准文档。
看起来,rel="preload"
的用法和上面两种没什么区别,都是通过更改某些属性,使得浏览器异步加载CSS文件但不解析,直到加载完成并将修改还原,然后开始解析。
但是它们之间其实有一个很重要的不同点,那就是使用preload,比使用不匹配的media
方法能够更早地开始加载CSS。所以尽管这一标准的支持度还不完善,仍建议优先使用该方法。
这应该是最容易想到的一个方法了,通过压缩CSS文件大小来提高页面加载速度。现在的构建工具,如webpack、gulp/grunt、rollup等也都支持CSS压缩功能。压缩后的文件能够明显减小,可以大大降低了浏览器的加载时间。
一般情况下,元素的嵌套层级不能超过3级,过度的嵌套会导致代码变得臃肿,沉余,复杂。导致css文件体积变大,造成性能浪费,影响渲染的速度!而且过于依赖HTML文档结构。这样的css样式,维护起来,极度麻烦,如果以后要修改样式,可能要使用!important
覆盖。尽量保持简单,不要使用嵌套过多过于复杂的选择器。
一般情况下,会存在这两种无用的CSS代码:一种是不同元素或者其他情况下的重复代码,一种是整个页面内没有生效的CSS代码。
对于前者,在编写的代码时候,我们应该尽可能地提取公共类,减少重复。对于后者,在不同开发者进行代码维护的过程中,总会产生不再使用的CSS的代码,当然一个人编写时也有可能出现这一问题。而这些无用的CSS代码不仅会增加浏览器的下载量,还会增加浏览器的解析时间,这对性能来说是很大的消耗。所以我们需要找到并去除这些无用代码。
那么我们如何知道哪些CSS代码是无用代码呢?
谷歌的Chrome浏览器就有这种开箱即用的功能。只需转到查看>开发人员>开发人员工具,并在最近的版本中打开Sources选项卡,然后打开命令菜单。然后,点击Coverage,在Coverage analysis窗口中高亮显示当前页面上未使用的代码。
我们有时候可能会写下面这种代码来消除一些标签的默认样式或统一浏览器对标签渲染的差异化:
*{ margin:0; padding:0; }
这样虽然代码量少,但它的性能可不是最佳的,我们最好还是写对应的标签选择器:
body,dl,dd,h1,h2,h3,h4,h5,h6,p,form,ol,ul{ margin:0; padding:0; }
开发时尽量避免使用通配符选择器
一般来讲一个网站上肯定会有很多个小图标,对于这些小图标,目前的主流的解决方案有三个,cssSprite(雪碧图),字体图标,把图片转成base64。
cssSprite
,只需要请求一次,大大的减少了http请求。缺点就是管理不灵活,如果需要新增一个图标,都需要改合并图片的源文件,图标定位也要规范,不然容易干扰图片之间的定位。8K以下的图片才转换成base64编码。
不建议使用@import
主要有以下两点原因:
使用@import
引入CSS会影响浏览器的并行下载。使用@import
引用的CSS文件只有在引用它的那个css文件被下载、解析之后,浏览器才会知道还有另外一个css需要下载,这时才去下载,然后下载后开始解析、构建render tree等一系列操作。这就导致浏览器无法并行下载所需的样式文件。
多个@impor
t会导致下载顺序紊乱。在IE中,@import
会引发资源文件的下载顺序被打乱,即排列在@import后面的js文件先于@import下载,并且打乱甚至破坏@import自身的并行下载。
在ID选择器前面嵌套其它选择器纯粹是多余的
.content #text
)完全是浪费性能。div#text
或者.box#text
。这两种方式完全是多余的,理由就是ID在页面就是唯一的。前面加任何东西都是多余的!CSS 支持多种单位和数字格式,可以删除尾随和跟随的零,零始终是零,添加维度不会为包含的信息附带任何价值。
.box { padding: .2px; margin: 20px; avalue: 0; }
在网站的使用过程中,某些操作会导致样式的改变,这时浏览器需要检测这些改变并重新渲染,其中有些操作所耗费的性能更多。我们都知道,当FPS为60时,用户使用网站时才会感到流畅。这也就是说,我们需要在16.67ms内完成每次渲染相关的所有操作,所以我们要尽量减少耗费更多的操作。
减少回流与重绘
合并对DOM
样式的修改,采用css class
来修改
const el = document.querySelector('.box') el.style.margin = '5px' el.style.borderRadius = '12px' el.style.boxShadow = '1px 3px 4px #ccc'
建议使用css class
.update{ margin: 5px; border-dadius: 12px; box-shadow: 1px 3px 4px #ccc } const el = document.querySelector('.box') el.classList.add('update')
如果需要对DOM进行多次访问,尽量使用局部变量缓存该DOM
避免使用table布局,可能很⼩的⼀个⼩改动会造成整个table的重新布局
CSS选择符从右往左匹配查找,避免节点层级过多
DOM离线处理,减少回流重绘次数
离线的DOM不属于当前DOM树中的任何一部分,这也就意味着我们对离线DOM处理就不会引起页面的回流与重绘。
display: none
,上面我们说到了 (display: none
) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分,之后在该DOM上的操作不会触发回流与重绘,操作完之后再将display
属性改为显示,只会触发这一次回流与重绘。提醒⏰:visibility : hidden
的元素只对重绘有影响,不影响重排。
dom
文档片段,在它上面批量操作 dom
,操作完成之后,再添加到文档中,这样只会触发一次重排。const el = document.querySelector('.box') const fruits = ['front', 'nanjiu', 'study', 'code']; const fragment = document.createDocumentFragment(); fruits.forEach(item => { const li = document.createElement('li'); li.innerHTML = item; fragment.appendChild(li); }); el.appendChild(fragment);
const el = document.querySelector('.box') const fruits = ['front', 'nanjiu', 'study', 'code']; const cloneEl = el.cloneNode(true) fruits.forEach(item => { const li = document.createElement('li'); li.innerHTML = item; cloneEl.appendChild(li); }); el.parentElement.replaceChild(cloneEl,el)
DOM脱离普通文档流
使用absoult
或fixed
让元素脱离普通文档流,使用绝对定位会使的该元素单独成为渲染树中 body
的一个子元素,重排开销比较小,不会对其它节点造成太多影响。
CSS3硬件加速(GPU加速)
使用css3硬件加速,可以让transform、opacity、filters
这些动画不会引起回流重绘 。但是对于动画的其它属性,比如background-color
这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。
常见的触发硬件加速的css属性:
将节点设置为图层
图层能够阻⽌该节点的渲染⾏为影响别的节点。⽐如对于video标签来说,浏览器会⾃动将该节点变为图层。
具体回流与重绘知识点可以看我这篇文章:https://juejin.cn/post/7064077572132323365
(学习视频分享:web前端)
The above is the detailed content of How to optimize CSS performance? Optimization Tips Sharing. For more information, please follow other related articles on the PHP Chinese website!