Brower-Loading-Principle

先大概了解浏览器加载历程下:

首先,解析和构建完全不同概念,这点要清楚…

其次,搞清楚顺序,只有先解析成浏览器能识别的字符串,才有DOM树的构建这一过程,因为构建的主语是浏览器。

然后,浏览器在构造DOM树的同时,也在构造着另一棵树 CSS-Tree(其实是CSS规则的不一样的叫法),与DOM树相对对应,所以暂且叫它-tree吧。

最后,就是Render-Tree的形成,然后各种layout、paint,最后Display。

跟着目录来:

渲染流水线:

大体上看:发送请求HTML文档–>等待HTML文档响应–>接收HTML文档的字符流响应–>渲染页面。

浏览器渲染机制 - 图:

细节结合图来看,可能更容易理解:
enter image description here

细节流程

  1. 发送HTML文档请求—>>接收HTML文档字符流响应;
  2. HTML的解析—>>开始DOM树结构的构建;
  3. 解析你的css脚本,于是寻找匹配并进行CSS-Rule的解析,即开始解析你写的CSS代码里的选择器,然后构建成 Style-Rules。
  4. 注意,注意,2和3是同时进行的。
    提示,如果你在初始化代码中,写了js操作dom代码,那么,这里只是能做到 解析js代码,看清楚,只是解析,相当于只是下载下来了,但不会去执行。因为css加载时是会阻塞js代码的运行的,其实就是阻塞了DOM的渲染。
  5. 好,DOM树和CSS树已经构建完成了…
  6. 再次注意,再次注意,这时候开始构建 Render-Tree了…
  7. 其实过程是一个个地遍历 DOM树上的 节点,然后再去匹配已经初始化好的 CSS 样式规则,然后符合规则的就 Attachment(翻译过来是连接,其实是css-rule附着到DOM节点上,firefox上叫frame) 成一个Render对象,然后挂到Render树上。
  8. 当一个个Render对象挂上后,就结束Rerder树的构建之旅了,就开始各种计算了;
  9. 开始layout(布局,即位置,大小等),然后paint(渲染,即字体,背景等);
  10. 还有,主要有一个Render对象被挂到Render树上,就有了Display属性了,就是show,就渲染在页面了 ,所以才会有你看到的页面是一点一点出来的,等所有对象挂上去Render树上了,才完成 Render 树的构建。

给我回去


DOM-Tree 是什么?

可以理解为你页面上所有的元素标签他们的节点,共同构建成一颗树,而这棵树就是所谓的DOM树。

给我回去

DOM-Tree 结构 - 解析:

就是将从服务器返回的html文档上的字符流,浏览器使用解析HTML的引擎,通过词法分析、语法分析,将字符流解析成类似head、div等能被浏览器识别并渲染的标签。
通过词法解析和语法解析从网络请求得到的字符流,然后处理成浏览器能识别的字符串。

  • 词法解析:即通过一系列类似正则的关键词,术语叫token,用来匹配我们的标签;
  • 语法解析:开始结束标签的配对、属性的赋值、父子关系的连接,最后构成dom树。

给我回去

DOM-Tree 结构的 - 构建:

其实可以这么简单理解,DOM树就是各个标签的node节点堆积而成的一堆你看不懂,而浏览器能看懂的代码。

说是这么说简单,但还是要细化出来的。

通过解析成元素标签后,每个元素底层都是一个个的node节点,然后把这些节点一个个挂到一颗树上,这里还包括了Display为none的元素的节点,那么这棵树就是所谓的DOM-结构树了,而形成这棵树的过程就是构建DOM树了。

给我回去

那这个CSS-tree是什么呢?

其实就是你写的各种CSS选择器以及css代码,形成的一个个规则对象。

为什么会有CSS-tree?

废话,肯定是匹配到Link或者style标签啊。
然后就是解析里面的CSS代码,解析成css引擎能识别的格式。
好,接下来就是解析了。
那浏览器怎么知道你这个css代码是要渲染页面的哪个位置呢?
CSS-选择器发挥作用的时候到了…
匹配的顺序是从右往左,这里一笔带过。点我去看看CSS-选择器匹配顺序

给我回去

CSS-tree的构建:

就是 CSS 选择器的匹配和代码的填充,填充到一个个的css-os,即 css 的一个个类对象的东西,等待和 DOM 节点 Attachment。

给我回去

Render-Tree - 示例图,废话和图更配哦~

Render-Tree-Deep

Render树又是啥?

我们页面看到的到底是什么树?
你首先要先知道Render-tree和DOM-tree以及CSS-tree之间的关系,可以这么看他们关系:Render-tree = Attachment = Dom-tree + Style-Rules
什么意思?

其实Render树就是我们页面看到的效果了,渲染树,是通过DOM树和CSS树连接而成的一棵树。上面挂了一个个 Html-Dom以及附着在 HTML-Dom上的Css-Dom。

其中,Render树每个节点都是一个对象,该对象结构上呈现矩形形状,其实这个就是控制台看到的盒子模型。

注意,我把上面这句话的看到给特别加粗了。
其实是说display为none的元素,这时候设置了该css样式的元素节点是不会被挂到Render树上的,所以你在页面就看不到了。

所以,Render-Tree 就是用来展示效果的。

给我回去

解析CSS-选择器的顺序:

还是一笔带过,从右往左
太简单?惊不惊喜?意不意外?下面更惊喜!

首先,先不说为什么,先说怎么知道的。
其实这是不成文的规定,是通过网络社区测试来的,至少我是不知道官方有这么说的,如果你知道,麻烦告知我。

接下来说说为什么?
上面提到了,Render树的构建,其实是遍历DOM节点然后挂到Render树的,那既然是遍历,那就要循环了,如果循环的判断条件不好,那就很浪费资源,导致算法算得慢,浏览器自然也慢了。

假设下,如果从左往右,第一个匹配到的肯定是父元素。但父元素可以有很多个啊。而且,即使是匹配对了左边的父元素,但匹配到最后,有可能不是目标元素,而很可能是兄弟元素,然后又要重头来匹配,浪费了时间和资源以及性能。
这样不就折腾了吗?

那这时候,从右到左的渲染规则,就起到作用了。

所以,一般,最右边的,一定就是被匹配的元素的class或者id等选择器了。
如果开始匹配到最右边的,有可能是目标元素,因为可能同名元素;
但是,如果连父元素都相同,那就没错了,就是你了。

这不,省了从左往右匹配的很大功夫了。

因此,很多浏览器也开始遵循这样的规则去构建Render树了。

给我回去

性能优化注意点:

会阻塞DOM树的构建的因素:

  • 请求HTML字符流的网络被阻塞了。
  • 构建DOM过程,遇到脚本的下载或加载,如script。
  • CSS样式文件的加载;

给我回去

会导致reflow、repaint的因素:

  • 操作DOM,这个毋庸置疑了。
  • 改变元素的大小和位置。
  • 改变元素的样式,如颜色。

给我回去

总结

照着js的万物接对象的理念下,把浏览器渲染一个网页的过程想象成一个大对象。
而构建这个对象的结构,就相当于是初始化网页。
会经过这样一个过程:
构建DOM树,CSS-Style,合成Render树,然后计算Render树上的属性,即layout,paint,最后添加Display。

一个文档(网页)就这么构建完成了。

browerS


Author: JawQ_
Link: http://wujiaqiang.com/2017/12/22/browerLoading/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.
支付宝-打赏
微信-打赏