html渲染节点有顺序,浏览器渲染HTML的主要过程

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

浏览器的主要功能是将用户选择得web资源呈现出来,它需要从服务器请求资源,并将其显示在浏览器窗口中,资源的格式通常是HTML,也包括PDF、image及其他格式。用户用URI(Uniform Resource Identifier 统一资源标识符)来指定所请求资源的位置。

HTML和CSS规范中规定了浏览器解释html文档的方式,由 W3C组织对这些规范进行维护,W3C是负责制定web标准的组织。

浏览器渲染主流程

渲染引擎首先通过网络获得所请求文档的内容,通常以8K分块的方式完成

下面是渲染引擎在取得内容之后的基本流程:

解析html以构建dom树->构建render树->布局render树->绘制render树

flow.png

浏览器渲染基本流程

当浏览器从网络上拿到html资源之后,渲染引擎开始解析html,并将标签转化为内容树中的dom节点,接着,它解析外部CSS文件及style标签中的样式信息。这些样式信息以及html中的可见性指令将被用来构建另一棵树——render树。

render树是由一些大大小小的矩形组成,这些矩形也有颜色背景什么的。当render树构建好了之后,就会执行布局过程,它将确定每个节点在屏幕上的确切坐标。再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。

webkit内核的浏览器绘制主流程如下图所示:

webkitflow.png

解析

就是文法词法分析语义分析啥的巴拉巴拉一大堆。

但是html的解析与平常我们所接触到的程序语言不同,他是非上下文无关文法。传统的解析方式在HTML上并不适用。

HTML Parser

HTML 解析器将html标识解析为解析树。

举个例子演示下html代码的解析过程:1

2

3

4

5

6

7

8

9

10

Hello DOM

%E2%80%9Dexample.png%E2%80%9D

他将会被解析成下面的dom树结构:

image015.png

过程:

1.初始状态为“Data State”

2.当遇到“

”,每个字符都附加到这个符号名上,例子中创建的是一个html符号。

3.状态又变回“Data State”

4.继续第二步的操作

这样直到遇到“”中的“”。然后,产生一个新的标签符号并回到“Data state”。后面的“”将和“”一样处理。

CSS parsing

css属于上下文无关文法,跟其他的一些语言解析原理相同比如java、JavaScript、c++等

image023.png

Parsing scripts

web的模式是同步的,开发者希望解析到一个script标签时立即解析执行脚本,并阻塞文档的解析直到脚本执行完。如果脚本是外引的,则网络必须先请求到这个资源——这个过程也是同步的,会阻塞文档的解析直到资源被请求到。这个模式保持了很多年,并且在html5中特别指定了。开发者可以将脚本标识为defer,以使其不阻塞文档解析,并在文档解析结束后执行。Html5增加了标记脚本为异步的选项,以使脚本的解析执行使用另一个线程。

渲染树的构造

当Dom树构建完成时,浏览器开始构建另一棵树——渲染树。渲染树由元素显示序列中的可见元素组成,它是文档的可视化表示,构建这棵树是为了以正确的顺序绘制文档内容。

Firefox将渲染树中的元素称为frames,webkit则用renderer或渲染对象来描述这些元素。

渲染对象和Dom元素相对应,但这种对应关系不是一对一的,不可见的Dom元素不会被插入渲染树,例如head元素。另外,display属性为none的元素也不会在渲染树中出现(visibility属性为hidden的元素将出现在渲染树中)。

还有一些Dom元素对应几个可见对象,它们一般是一些具有复杂结构的元素,无法用一个矩形来描述。例如,select元素有三个渲染对象——一个显示区域、一个下拉列表及一个按钮。同样,当文本因为宽度不够而折行时,新行将作为额外的渲染元素被添加。另一个多个渲染对象的例子是不规范的html,根据css规范,一个行内元素只能仅包含行内元素或仅包含块状元素,在存在混合内容时,将会创建匿名的块状渲染对象包裹住行内元素。

一些渲染对象和所对应的Dom节点不在树上相同的位置,例如,浮动和绝对定位的元素在文本流之外,在两棵树上的位置不同,渲染树上标识出真实的结构,并用一个占位结构标识出它们原来的位置。

image025.png

当渲染树构造好了之后就要开始把构造好的渲染树给绘制到界面上去。

布局 Layout

当渲染对象被创建并添加到树中,它们并没有位置和大小,计算这些值的过程称为layout或reflow。

坐标系统相对于根节点,使用top和left坐标。

布局是一个递归的过程,由根渲染对象开始,它对应html文档元素,布局继续递归的通过一些或所有的frame层级,为每个需要几何信息的渲染对象进行计算。

根渲染对象的位置是0,0,它的大小是viewport-浏览器窗口的可见部分。

layout一般有下面这几个部分:

1.parent渲染对象决定它的宽度

2.parent渲染对象读取chilidren,并放置child渲染对象(设置它的x和y)在需要时(它们当前为dirty或是处于全局layout或者其他原因)调用child渲染对象的layout,这将计算child的高度

3.parent渲染对象使用child渲染对象的累积高度,以及margin和padding的高度来设置自己的高度-这将被parent渲染对象的parent使用

4.将dirty标识设置为false

绘制顺序

1.背景色

2.背景图

3.border

4.children

5.outline

重绘与回流

Reflow(回流):浏览器要花时间去渲染,当它发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。

Repaint(重绘):如果只是改变了某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的

注意:回流必将引起重绘,而重绘不一定会引起回流。

重绘何时发生:改变了某个元素的背景颜色,文字颜色等

1、改变某个元素的背景颜色

2、元素的字体颜色改变

回流何时发生:

当页面布局和几何属性改变时就需要回流。下述情况会发生浏览器回流:

1、添加或者删除可见的DOM元素;

2、元素位置改变;

3、元素尺寸改变——边距、填充、边框、宽度和高度

4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;

5、页面渲染初始化;

6、浏览器窗口尺寸改变——resize事件发生时;

如何减少回流、重绘

1.直接改变className,如果动态改变样式

2.拿变量保留offsetWidth

3.当我们需要向文档中添加节点时,可以用文档碎片的方式去解决这个问题的,当我们需要给DOM中添加新的元素的时候,先将其放在一个容器中,然后统一添加,这样就只产生了一次回流。

4.具有动画效果使用absolute

5.减少使用CSS表达式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值