CSS性能优化的小技巧,让老板给你加工资 我就是我 2022-03-15 09:50 136阅读 0赞 我们都知道对于网站来说,性能至关重要,CSS作为页面渲染和内容展现的重要环节,影响着用户对整个网站的第一体验。因此,与其相关的性能优化是不容忽视的。 对于性能优化我们常常在项目完成时才去考虑,经常被推迟到项目的末期,甚至到暴露出严重的性能问题时才进行性能优化,相信大多数人对此深有体会。 ![1240][] 下面我们开始介绍**实践型的4个优化技巧**,先从首屏关键CSS开始。 **1. 内联首屏关键CSS(Critical CSS)** 性能优化中有一个重要的指标——**首次有效绘制**(First Meaningful Paint,简称FMP)即指页面的首要内容(primary content)出现在屏幕上的时间。这一指标影响用户看到页面前所需等待的时间,而\*\*内联首屏关键CSS(即Critical CSS,可以称之为首屏关键CSS)\*\*能减少这一时间。 大家应该都习惯于通过link标签引用外部CSS文件。但需要知道的是,将CSS直接内联到HTML文档中能使CSS更快速地下载。而使用外部CSS文件时,需要在HTML文档下载完成后才知道所要引用的CSS文件,然后才下载它们。所以说,**内联CSS能够使浏览器开始页面渲染的时间提前**,因为在HTML下载完成之后就能渲染了。 既然内联CSS能够使页面渲染的开始时间提前,那么是否可以内联所有的CSS呢?答案显然是否定的,这种方式并不适用于内联较大的CSS文件。因为初始拥塞窗口3存在限制(TCP相关概念,通常是 14.6kB,压缩后大小),如果内联CSS后的文件超出了这一限制,系统就需要在服务器和浏览器之间进行更多次的往返,这样并不能提前页面渲染时间。因此,我们应当**只将渲染首屏内容所需的关键CSS内联到HTML中**。 既然已经知道内联首屏关键CSS能够优化性能了,那下一步就是如何确定首屏关键CSS了。显然,我们不需要手动确定哪些内容是首屏关键CSS。Github上有一个项目Critical CSS4,可以将属于首屏的关键样式提取出来,大家可以看一下该项目,结合自己的构建工具进行使用。当然为了保证正确,大家最好再亲自确认下提取出的内容是否有缺失。 不过内联CSS有一个缺点,内联之后的CSS不会进行缓存,每次都会重新下载。不过如上所说,如果我们将内联后的文件大小控制在了14.6kb以内,这似乎并不是什么大问题。 如上,我们已经介绍了为什么要内联关键CSS以及如何内联,那么剩下的CSS我们怎么处理好呢?建议使用外部CSS引入剩余CSS,这样能够启用缓存,除此之外还可以异步加载它们。 **2. 异步加载CSS** CSS会阻塞渲染,在CSS文件请求、下载、解析完成之前,浏览器将不会渲染任何已处理的内容。有时,这种阻塞是必须的,因为我们并不希望在所需的CSS加载之前,浏览器就开始渲染页面。那么将首屏关键CSS内联后,剩余的CSS内容的阻塞渲染就不是必需的了,可以使用外部CSS,并且异步加载。 那么如何实现CSS的异步加载呢?有以下四种方式可以实现浏览器异步加载CSS。 第一种方式是使用JavaScript动态创建样式表link元素,并插入到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 );复制代码 第二种方式是将link元素的media属性设置为用户浏览器不匹配的媒体类型(或媒体查询),如media="print",甚至可以是完全不存在的类型media="noexist"。对浏览器来说,如果样式表不适用于当前媒体类型,其优先级会被放低,会在不阻塞页面渲染的情况下再进行下载。 当然,这么做只是为了实现CSS的异步加载,别忘了在文件加载完成之后,将media的值设为screen或all,从而让浏览器开始解析CSS。 复制代码 与第二种方式相似,我们还可以通过rel属性将link元素标记为alternate可选样式表,也能实现浏览器异步加载。同样别忘了加载完成之后,将rel改回去。 复制代码 上述的三种方法都较为古老。现在,rel="preload"5这一Web标准指出了如何异步加载资源,包括CSS类资源。 复制代码 注意,as是必须的。忽略as属性,或者错误的as属性会使preload等同于XHR请求,浏览器不知道加载的是什么内容,因此此类资源加载优先级会非常低。as的可选值可以参考上述标准文档。 看起来,rel="preload"�的用法和上面两种没什么区别,都是通过更改某些属性,使得浏览器异步加载CSS文件但不解析,直到加载完成并将修改还原,然后开始解析。 但是它们之间其实有一个很重要的不同点,那就是**使用preload,比使用不匹配的media方法能够更早地开始加载CSS**。所以尽管这一标准的支持度还不完善,仍建议优先使用该方法。 该标准现在已经是候选标准,相信浏览器会逐渐支持该标准。在各浏览器的支持度如下图所示。 ![1240 1][] 从上图可以看出这一方法在现在的浏览器中支持度不算乐观,不过我们可以通过loadCSS6进行polyfill,所以支持不支持,这都不是事儿。 **3. 文件压缩** 性能优化时有一个最容易想到,也最常使用的方法,那就是文件压缩,这一方案往往效果显著。 文件的大小会直接影响浏览器的加载速度,这一点在网络较差时表现地尤为明显。相信大家都早已习惯对CSS进行压缩,现在的构建工具,如webpack、gulp/grunt、rollup等也都支持CSS压缩功能。压缩后的文件能够明显减小,可以大大降低了浏览器的加载时间。 **4. 去除无用CSS** 虽然文件压缩能够降低文件大小。但CSS文件压缩通常只会去除无用的空格,这样就限制了CSS文件的压缩比例。那是否还有其他手段来精简CSS呢?答案显然是肯定的,如果压缩后的文件仍然超出了预期的大小,我们可以试着**找到并删除代码中无用的CSS**。 一般情况下,会存在这两种无用的CSS代码:一种是不同元素或者其他情况下的重复代码,一种是整个页面内没有生效的CSS代码。对于前者,在编写的代码时候,我们应该尽可能地提取公共类,减少重复。对于后者,在不同开发者进行代码维护的过程中,总会产生不再使用的CSS的代码,当然一个人编写时也有可能出现这一问题。而这些无用的CSS代码不仅会增加浏览器的下载量,还会增加浏览器的解析时间,这对性能来说是很大的消耗。所以我们需要找到并去除这些无用代码。 当然,如果手动删除这些无用CSS是很低效的。我们可以借助Uncss7库来进行。Uncss可以用来移除样式表中的无用CSS,并且支持多文件和JavaScript注入的CSS。 前面已经说完了实践型的4个优化技巧,下面我们介绍下**建议型的4个技巧**。 ![1240 2][] 不过现代浏览器在这一方面做了很多优化,不同选择器的性能差别并不明显,甚至可以说差别甚微。此外不同选择器在不同浏览器中的性能表现8也不完全统一,在编写CSS的时候无法兼顾每种浏览器。鉴于这两点原因,我们在使用选择器时,只需要记住以下几点,其他的可以全凭喜好。 保持简单,不要使用嵌套过多过于复杂的选择器。 通配符和属性选择器效率最低,需要匹配的元素最多,尽量避免使用。 不要使用类选择器和ID选择器修饰元素标签,如h3\#markdown-content,这样多此一举,还会降低效率。 不要为了追求速度而放弃可读性与可维护性。 下面是小编整理的一整套系统的web前端学习教程,加群即可免费领取! 自己整理了一份最全面前端学习资料,从最基础的HTML+CSS+JS \[炫酷特效,游戏,插件封装,设计模式\]到移动端HTML5的项目实战的学习资料都有整理,送给每一位前端小伙伴, 有想学习web前端的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习。 加Q 裙:853597293(招募中) ![1240 3][] 以上素材来源于网络,如有侵权,请联系作者删除! [1240]: /images/20220315/f996e7c873ad499092f15e81be7f8ace.png [1240 1]: /images/20220315/c16d4af689bd4df88cff1d6280789fd1.png [1240 2]: /images/20220315/a6da552c818b4c61aaaf70cd412d8edb.png [1240 3]: /images/20220315/9bbf4d62b95a4858887eb98a143a867c.png
还没有评论,来说两句吧...