🍏 CSS 性能优化相关
相关问题:
- 如果提高 CSS 的性能?
# 实现方式
主要有以下的方面入手:
- 内联首屏关键 CSS
- 异步加载 CSS
- 资源压缩
- 合理使用选择器
- 减少使用昂贵的属性
- 不要使用
@import
# 内联首屏关键 CSS / Critical CSS
打开一个页面,页面的首要内容出现在屏幕的事件影响着用户的体验。而通过内联 CSS 关键代码能够使得浏览器在下载完 HTML 之后立刻渲染。
而如果外部引用 CSS 代码,只有在在解析 HTML 结构的过程中遇到了外部 CSS 文件,才会开始下载 CSS 代码,再进行渲染。
所以,内联使用 CSS 样式可以使渲染时间提前。
但是,较大的 CSS 代码不适合内联(会造成初始拥塞窗口、没有缓存),而其余的代码采取外部引用的方式。
# 异步加载 CSS
CSS 文件请求、下载、解析完成之前,CSS 会造成阻塞渲染,浏览器将不会渲染任何已处理的内容。
在加载内联 CSS 代码后,后面的外部引用 CSS 没必要阻塞浏览器渲染。这时可以采取异步加载的方案,主要有以下:
使用 JavaScript 将
link
标签插入到head
标签的最后:const myCSS = document.createElement("link") myCSS.rel = "stylesheet" myCSS.href = "mystyles.css" document.head.insertBefore(myCss, docuemnt.head.childNodes[document.head.childNodes.length - 1].nextSibiling)
1
2
3
4设置
link
标签的media
属性为noexist
,浏览器会认为当前样式表不使用当前类型,会在不阻塞页面渲染的情况下再进行下载。加载完毕之后,将media
的值设置为screen
或者all
,从而让浏览器开始解析 CSS。<link rel="stylesheet" href="mystyle.css" media=noexist` onload="this.media='all'">
1通过
rel
属性将link
元素标记为alternate
可选样式表,也能实现浏览器的异步加载。在加载完成之后,rel
设置回为stylesheet
:<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">
1
# 资源压缩
利用 webpack
、 gulp
/ grunt
、 rollup
等模块化工具,可以将 CSS 的代码进行压缩,使得文件变小,大大降低浏览器的加载时间。
# 合理使用 CSS 选择器
CSS 的匹配规则是 从右向左 开始匹配。
🌰 例子 / 例如 #markdown .content h3
匹配的规则如下:
- 先找到
h3
标签的元素; - 然后去除祖先不是
.content
类的元素; - 最后取出祖先不是
#markdown
的元素;
如果嵌套的层级更多,页面中的元素更多,那么匹配所要话费的时间代价更高。所以在编写选择器时,应该遵循以下规则:
- 不要嵌套使用过多复杂的选择器,最好不要三层以上;
- 使用
id
选择器就没有必要再进行嵌套; - 通配符
*
和属性选择器效率最低,避免使用;
#
# 减少使用昂贵的属性
页面发生重绘的时候,昂贵属性例如 box-shadow
/ border-radius
/ filter
/ transparent
/ :nth-child
等属性,会降低 浏览器的渲染性能。
# 不要使用 @import
CSS 样式文件有两种引入的方式,一种是 link
元素,另一种是 @import
。 @import
会影响浏览器的并行下载,使得页面在加载的时候增加额外的延迟,增添额外的往返耗时。
并且多个 @import
可能会导致下载顺序紊乱。
🌰 例子:如果一个 CSS 文件 index.css
中包含了以下的导入内容: @import url("reset.css")
,那么浏览器就必须先把 index.css
下载、解析和执行后,才下载、解析和执行第二个文件 reset.css
。
# 其他
- 减少重排的操作,以及减少不必要的重绘;
- 了解哪些属性可以继承而来,避免对这些属性重复编写;
- 动画或者过渡尽量使用
transform
和opacity
,避免使用left
和top
属性。