CSS 渲染原理与优化

CSS 渲染原理与优化

一. 浏览器构成

浏览器的抽象分层结构图中将浏览器分成了以下8个子系统:

1.用户界面(User Interface)

用户界面主要包括工具栏、地址栏、前进/后退按钮、书签菜单、可视化页面加载进度、智能下载处理、首选项、打印等。除了浏览器主窗口显示请求的页面之外,其他显示的部分都属于用户界面。
用户界面还可以与桌面环境集成,以提供浏览器会话管理或与其他桌面应用程序的通信。

2.浏览器引擎(Browser Engine)

浏览器引擎是一个可嵌入的组件,其为渲染引擎提供高级接口。
浏览器引擎可以加载一个给定的URI,并支持诸如:前进/后退/重新加载等浏览操作。
浏览器引擎提供查看浏览会话的各个方面的挂钩,例如:当前页面加载进度、JavaScript alert。
浏览器引擎还允许查询/修改渲染引擎设置。

3渲染引擎(Rendering Engine)

渲染引擎为指定的URI生成可视化的表示。
渲染引擎能够显示HTML和XML文档,可选择CSS样式,以及嵌入式内容(如图片)。
渲染引擎能够准确计算页面布局,可使用“回流”算法逐步调整页面元素的位置。
渲染引擎内部包含HTML解析器。

4.网络(Networking)

网络系统实现HTTP和FTP等文件传输协议。 网络系统可以在不同的字符集之间进行转换,为文件解析MIME媒体类型。 网络系统可以实现最近检索资源的缓存功能。

5.JavaScript解释器(JavaScript Interpreter)

JavaScript解释器能够解释并执行嵌入在网页中的JavaScript(又称ECMAScript)代码。 为了安全起见,浏览器引擎或渲染引擎可能会禁用某些JavaScript功能,如弹出窗口的打开。

6.XML解析器(XML Parser)

XML解析器可以将XML文档解析成文档对象模型(Document Object Model,DOM)树。 XML解析器是浏览器架构中复用最多的子系统之一,几乎所有的浏览器实现都利用现有的XML解析器,而不是从头开始创建自己的XML解析器。

7.显示后端(Display Backend)

显示后端提供绘图和窗口原语,包括:用户界面控件集合、字体集合。

8.数据持久层(Data Persistence)

数据持久层将与浏览会话相关联的各种数据存储在硬盘上。 这些数据可能是诸如:书签、工具栏设置等这样的高级数据,也可能是诸如:Cookie,安全证书、缓存等这样的低级数据。
这里可能会产生一个疑问:功能相似的HTML解析器和XML解析器为什么前者划分在渲染引擎中,后者作为独立的系统?
原因:XML解析器对于系统来说,其功能并不是关键性的,但是从复用角度来说,XML解析器是一个通用的,可重用的组件,具有标准的,定义明确的接口。相比之下,HTML解析器通常与渲染引擎紧耦合。

二.渲染引擎模块

渲染引擎,解析 DOM 文档和 CSS 规则并将内容排版到浏览器中显示有样式的界面,也就是排版引擎,我们常说的浏览器内核主要指的就是渲染引擎。
渲染引擎主要包含(或调用)的模块有:

1.HTML(XML)解析器

解析HTML(XML)文档,主要作用是将HTML(XML)文档转换成DOM树。

2.CSS解析器

将DOM中的各个元素对象进行计算,获取样式信息,用于渲染树的构建。

3.JavaScript解释器

使用JavaScript可以修改网页的内容、CSS规则等。JavaScript解释器能够解释JavaScript代码,并通过DOM接口和CSSOM接口来修改网页内容、样式规则,从而改变渲染结果。

4.布局

DOM创建之后,渲染引擎将其中的元素对象与样式规则进行结合,可以得到渲染树。布局则是针对渲染树,计算其各个元素的大小、位置等布局信息。

5.绘图

使用图形库将布局计算后的渲染树绘制成可视化的图像结果。

三.CSS优先级

权重,代表着优先级,权重越大,优先级越高。同种类型的选择器权值相同,后定义的选择器会覆盖先定义的选择器。
!important > 行内样式(权重1000) > ID 选择器(权重 100) > 类选择器(权重 10) > 标签(权重1) > 通配符 > 继承 > 浏览器默认属性
注: 组合使用,权重会叠加

四.继承性

继承得到的样式的优先级是最低的,在任何时候,只要元素本身有同属性的样式定义,就可以覆盖掉继承值;
在这里插入图片描述

五.CSS 渲染规则

css的渲染规则,是从上到下,从右到左渲染的。

.main h4 a { font-size: 14px; }

渲染过程是这样的:首先先找到所有的 a,沿着 a 的父元素查找h4,然后再沿着 h4,查找.main。中途找到了符合匹配规则的节点就加入结果集。如果找到根元素的 html 都没有匹配,则这条路径不再遍历。下一个 a 开始重复这个查找匹配,直至没有a继续查找。
浏览器的这种查找规则是为了尽早过滤掉一些无关的样式规则和元素。

六.CSS 书写顺序

书写顺序会对 CSS 性能有影响吗,这是个值得思考的问题。
需要注意的是:浏览器并不是一获取到 CSS 样式就立马开始解析,而是根据 CSS 样式的书写顺序将之按照 DOM 树的结构分布渲染样式,然后开始遍历每个树结点的 CSS 样式进行解析,此时的 CSS 样式的遍历顺序完全是按照之前的书写顺序。
在解析过程中,一旦浏览器发现某个元素的定位变化影响布局,则需要倒回去重新渲染。
我们来看看下面这个代码片段:

.box{
    width: 150px;
    height: 150px;
    font-size: 24px;
    position: absolute;
}

当浏览器解析到 position 的时候突然发现该元素是绝对定位元素需要脱离文档流,而之前却是按照普通元素进行解析的,所以不得不重新渲染。
渲染引擎首先解除该元素在文档中所占位置,这就导致了该元素的占位情况发生了变化,其他元素可能会受到它回流的影响而重新排位。
我们对代码进行调整:

.box{
    position: absolute;
    width: 150px;
    height: 150px;
    font-size: 24px;

这样就能让渲染引擎更高效的工作

七.CSS优化

1. 把 Stylesheets 放在 HTML 页面头部

浏览器在所有的 stylesheets 加载完成之后,才会开始渲染整个页面,在此之前,浏览器不会渲染页面里的任何内容,页面会一直呈现空白。这也是为什么要把 stylesheet 放在头部的原因。如果放在 HTML 页面底部,页面渲染就不仅仅是在等待 stylesheet 的加载,还要等待 html 内容加载完成,这样一来,用户看到页面的时间会更晚。

2.不要使用 @import

使用 @import 引入 CSS 会影响浏览器的并行下载。使用 @import 引用的 CSS 文件只有在引用它的那个 CSS 文件被下载、解析之后,浏览器才会知道还有另外一个 CSS 需要下载,这时才去下载,然后下载后开始解析、构建 Render Tree 等一系列操作。

3. 嵌套层级不要超过三级

一般情况下,嵌套层级不要超过三级,过渡的嵌套会导致代码变得臃肿,导致css文件体积变大,造成性能上的浪费,影响渲染的速度;css层级太多,也过于依赖html DOM结构,不易于维护。如果层级比较深,就直接定义一个class代替多余的层级。

4. css 命名规范,书写规范。

5. 多用继承属性

尽量的继承父类样式 ,重复的定义会造成很多不必要的性能浪费。

6.使用简写样式。见下例

.box {
    margin-top: 20px;
    margin-right: 0px;
    margin-bottom: 20px;
    margin-left: 100px;
  }

可以简写为

.box {
    margin: 20px 0px 20px 100px;
  }

7.不要再id选择器和class选择器前使用标签名 例如:

div #box {
    color: white;
  }

id选择器本身就能唯一确定一个元素,没必要再在前面加上标签名。同样,类选择器也是,如果需要给某个标签的类增添额外的样式,建议使用另一个类名。这种情况下,也可以使用 div .box{} 形式,差别不大。

8. 尽量少用通配符,只用通配符设定一切基础的样式,如:

 * {margin:0; padding:0;}
 

9.避免过分重排(Reflow)

浏览器重新计算布局位置与大小。

常见的重排元素;

width、height 、padding 、margin 、display 、border-width 、border 、top
、position 、font-size 、float 、text-align 、overflow-y 、font-weight 、overflow
、left 、font-family 、line-height 、vertical-align 、right 、clear 、white-space
、bottom 、min-height

怎么减少 Reflow
  • 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className

  • 把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,然后再把它显示出来

  • 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量

  • 尽可能不要修改影响范围比较大的 DOM

  • 为动画的元素使用绝对定位 absolute / fixed

  • 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局

10. 避免过分重绘(Repaints)

当元素改变的时候,将不会影响元素在页面当中的位置(比如 background-color, border-color, visibility),浏览器仅仅会应用新的样式重绘此元素,此过程称为 Repaint。

常见的重绘元素

color、 border-style、 visibility、 background、
text-decoration、 background-image、 background-position、 background-repeat、
outline-color、 outline、 outline-style border-radius、
outline-width、 box-shadow background-size、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值