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都内联在HTML文档中,因为[初始拥塞窗口]存在限制(
TCP相关概念,通常是 14.6kB,压缩后大小),
如果内联CSS后的文件超出了这一限制,系统就需要在服务器和浏览器之间进行更多次的往返
,这样并不能提前页面渲染时间。因此,我们应当只将渲染首屏内容所需的关键CSS内联到HTML中。
⚠️还有一点需要注意的是内联CSS没有缓存,每次都会随HTML的加载而重新下载,
但我们将内联首屏关键CSS控制在 14.6kB以内,它对性能优化还是起到正向作用的。(凡事有利也有弊)
2、异步加载非首屏CSS
由于CSS会阻塞DOM的渲染,所以我们将首屏关键CSS内联后,
剩余的非首屏CSS内容可以使用外部CSS,并且异步加载,
防止非首屏CSS内容阻塞页面的渲染。
3、CSS异步加载方式
// 创建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" οnlοad="this.media='all'">
<link rel="alternate stylesheet" href="mystyles.css" οnlοad="this.rel='stylesheet'">
<link rel="preload" href="mystyles.css" as="style" οnlοad="this.rel='stylesheet'">
删除无用CSS代码
一般情况下,会存在这两种无用的CSS代码:
一种是不同元素或者其他情况下的重复代码,一种是整个页面内没有生效的CSS代码。
Sources选项卡,然后打开命令菜单。然后,
点击Coverage,在Coverage analysis窗口中高亮显示当前页面上未使用的代码。
讲道理,感觉都有用
没用的可能是媒体查询,没有命中
总结
- 慎用*通配符
- css文件压缩和缓存
- CSS层级嵌套最好不要超过3层
- cssSprite(雪碧图),字体图标,把8K下图片转成base64
- 不要在ID选择器前面进行嵌套其它选择器
- 避免使用@import
- 删除不必要的单位和零
- 减少回流与重绘
- 合并对DOM样式的修改,采用css class来修改
- DOM离线处理,减少回流重绘次数
- DOM脱离普通文档流
- CSS3硬件加速(GPU加速)
- 常见的触发硬件加速的css属性:
transform
opacity
filters
Will-change - 将节点设置为图层
图层能够阻⽌该节点的渲染⾏为影响别的节点。
⽐如对于video标签
实践
图片预加载
<link rel="preload" as="image" href={url} key={url} />
<link rel="dns-prefetch" href="//baidu.com" />
<link rel="preconnect" href="//baidu.com" />