游览器经过和后端的连接获取到相关的资源数据后,浏览器需要对获取的网页数据进行解析、渲染、绘制,最终展示出来的就是我们所看到的界面内容。
渲染页面主要分为以下几个阶段
- 开始解析HTML,获取外部资源,构建DOM
- 解析CSS并构建CSSOM
- 执行javaScript
- 合并DOM和CSSOM以构造渲染树
- 计算布局并绘制
1.DOM
浏览器渲染页面的过程就像其实就像盖房子的过程,一般先请求服务器得到html文件(拿到施工合同和框架结构模型),html相当于网页的框架结构。
获取到框架结构模型
1.字节: 浏览器先得到的是字节内容的html文件。
2.字符: 必须进行转化成浏览器识别的语言,于是将字节转化为字符(即程序员可看懂的代码)。
3.Token: 再转化为html标记语言(里面有很多小于号<和大于号>分别识别不同的结构),于是浏览器就把字符串转化为Token,可简单把token理解为符号标签。
4.节点: 比如遇到第一个的时候转化为一个起始标签,遇到结尾的 时转化为结束标签,这样字符就被token化了,不同的字符就变成了有不同特殊意义东西了。
5.DOM: token升华了,就把token变为了节点对象,在对象里面对象虽然只是用代码表示而已,但是对象是可以进行编程操作的,对象有自己的属性和方法,相当于将token盘活了,最后就是把这些节点对象都连在一起,形成文本对象模型,即DOM,DOM即浏览器自己的语言,每个节点对象相连,形成父子关系,这样后面对某个节点进行操作就友好了。
2.CSSOM
从html转变为DOM(正如把施工合同转变为迷你框架结构模型,在阅读施工合同的时候,也阅读了甲方的装饰要求,在制作迷你框架结构模型的同时也给模型装修,给墙面上色之类的。)
一般来说我们会把css样式作为外链加入到link标签里,css相当于网页装饰,浏览器在遇见DOM的时候就遇见link标签,然后向服务器发送请求,接着得到css文件,后面就像处理html文件类似,字节——>字符——>Token——>节点——>这里节点会结合css对象模型,即CSSOM。
3.渲染树
虽然DOM和CSSOM都是独立的对象模型,但是一个网页的呈现离不开两者,一个网页就是由框架结构和样式结合起来, DOM和CSSOM的爱情结晶就叫渲染树。
页面就是要根据渲染树的结构样式来进行的,因为渲染树上的节点是页面能够呈现的内容,即 一些html和某些样式不会被呈现出来,不会被呈现出来就不会被挂在渲染树上, 比如mete和link就不会被当做标签呈现出来,设置了display:none;的样式也不会被呈现出来。
4.布局和绘制
渲染树的任务就是匹配DOM和CSSOM的节点,并且捕获可见内容,在页面被构建完,是不能被立即渲染的,还需要布局,布局的意思是获取渲染树的结构,节点位置和大小, 而布局是根据盒子模型来进行的,也就是每个元素都用一个盒子来表示,然后这些盒子在页面上进行排列和嵌套,浏览器在布局以后其实就可安排页面绘制了,把渲染树以像素的形式渲染在页面,页面就可呈现。
5.过程分析
浏览器发送请求,服务器或者本地返回给浏览器HTML文件,第一步就是解析html文件,返回html文件并且构建DOM,在解析HTML文件的时候就遇到了link标签,浏览器就去请求CSS文件,请求CSS文件的同时继续解析HTML文件,此时遇到了script标签,浏览器就去请求JS文件,服务器或者本地就会陆续返回CSS和JS文件,实际操作中先得到CSS还是JS文件是要看具体情况的。
重点:在这里,如果先返回并且解析完成JS文件也是会发生阻塞,我们不能先执行CSS文件,必须等到CSSOM构建完成了才能执行JS文件,因为渲染树是需要DOM和CSSOM构建完成了以后才能构建,而且JS是控制CSS样式的,所以这一步就是解析CSS文件并且构建CSSOM。
而如果标签里面是行内JS代码,而不是外部JS文件,也会发生阻塞,CSSOM的构建就是渲染中一个重要的阻塞因素,其实DOM也是会阻塞渲染过程,毕竟没有DOM,网页的框架都建造不起来DOM有个好处就是部分解析,而CSSOM不能部分解析。
DOM能部分解析,CSSOM不能部分解析的原因:
例如:我们为body设置字体32px,还给里面的div设置字体为16px,如果CSSSOM只解析body,后面的div没有解析或者延迟解析,就会乱,所以CSSOM不能进行部分解析,不过在解析CSS文件并且构建CSSOM的时候,浏览器依旧可以下载并解析JS文件,等CSSOM构建完成以后就可以执行JS里的内容了。
这里停止的原因是JS会阻塞HTML解析的,虽然看起来JS没有直接阻塞渲染的过程,但是有间接的影响,因为JS可操作DOM,又可以操作CSSOM,如果不等JS下载解析完以后再构建DOM,那就有可能网页的有些内容出现了又消失,所以在解析HTML的时候,不管是行内JS代码还是外部JS文件,都会让HTML的解析停止下来,虽然DOM是可以部分解析的,但是对于这个网页来说相当于阻塞了第一次的渲染,JS完成之前什么内容都没有,在JS执行完了以后,下面的流程就正常了,也就是形成了渲染树(构建DOM后),进行布局,最后绘制。