浏览器渲染页面过程
Posted fan-1994716
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器渲染页面过程相关的知识,希望对你有一定的参考价值。
简单点来说就是创建了dom以后,还未完全渲染,就去获取dom的高度,显然是会出问题的。代码如下,可找个图片自行体会:
<div id="bgImg"></div>
<div id="bgImg"></div>
<script>
document.body.scrollHeight;
var odiv = document.getElementById(‘bgImg‘);
odiv.innerhtml = ‘<img src="test.jpg">‘
var oHeight = odiv.scrollHeight;
console.log(oHeight);
</script>
123456789
那么为了更好的理解这个问题,咱们今天来聊聊浏览器的渲染过程:
document.body.scrollHeight;
var odiv = document.getElementById(‘bgImg‘);
odiv.innerhtml = ‘<img src="test.jpg">‘
var oHeight = odiv.scrollHeight;
console.log(oHeight);
</script>
123456789
那么为了更好的理解这个问题,咱们今天来聊聊浏览器的渲染过程:
解析HTML
解析CSS
构建Render Tree
布局(Layout)
绘制(Painting)
解析CSS
构建Render Tree
布局(Layout)
绘制(Painting)
1. 解析HTML,构建DOM
浏览器获取到网页文件以后,怎么将代码生成美丽的页面呢?
首先需要将网站的结构搭建起来,类似于人的全身骨骼,解析HTML做的就是这个事情。解析HTML的所有标签,然后深度遍历生成DOM Tree,如图所示
浏览器获取到网页文件以后,怎么将代码生成美丽的页面呢?
首先需要将网站的结构搭建起来,类似于人的全身骨骼,解析HTML做的就是这个事情。解析HTML的所有标签,然后深度遍历生成DOM Tree,如图所示
2. 解析CSS,构建CSSOM
有了骨骼以后,接下来就是确定长相了,这是CSS要做的事情。和解析HTML类似,CSS解析各种样式信息,生成网页的“外观”。但是有个问题,CSSA(class选择器)说,我喜欢蓝色,我家网页的所有文字都要是蓝色。CSSB(id选择器)就不乐意了,凭啥啊,我喜欢红色,我家的标题必须是红色。由于id选择器是亲生的,那就标题是红色的吧,于是不同选择器就有了不同的权重。最后生成CSSOM,如图所示
有了骨骼以后,接下来就是确定长相了,这是CSS要做的事情。和解析HTML类似,CSS解析各种样式信息,生成网页的“外观”。但是有个问题,CSSA(class选择器)说,我喜欢蓝色,我家网页的所有文字都要是蓝色。CSSB(id选择器)就不乐意了,凭啥啊,我喜欢红色,我家的标题必须是红色。由于id选择器是亲生的,那就标题是红色的吧,于是不同选择器就有了不同的权重。最后生成CSSOM,如图所示
2.5 JS脚本加载
为啥要2.5呢,因为浏览器解析文档,当遇到 <script>标签的时候,会立即解析脚本,停止解析文档(因为JS可以操作DOM和CSS,可能会改动DOM和CSS,所以继续解析会造成浪费)。如果脚本是外部的,会等待脚本下载完毕,再继续解析文档。所以常见的做法是将js放到页脚部分。
3. 构建Render Tree(呈现树)
骨骼和长相都有了,那就组合到一起呗,DOM和CSSOM根据一定的规则组合起来生成了Render Tree。如下图:
为啥要2.5呢,因为浏览器解析文档,当遇到 <script>标签的时候,会立即解析脚本,停止解析文档(因为JS可以操作DOM和CSS,可能会改动DOM和CSS,所以继续解析会造成浪费)。如果脚本是外部的,会等待脚本下载完毕,再继续解析文档。所以常见的做法是将js放到页脚部分。
3. 构建Render Tree(呈现树)
骨骼和长相都有了,那就组合到一起呗,DOM和CSSOM根据一定的规则组合起来生成了Render Tree。如下图:
4. 布局(Layout)
创建渲染树后,接下来正式开工,确定各个元素的位置,包括元素在视图中的位置以及自身的大小,将其安置在浏览器的正确位置。
5. 绘制(Painting)
这个阶段,浏览器会遍历呈现树,并调用呈现器的“paint”方法,将前期所有的工作结合到一起,将网页的内容呈现出来。如果网页只是HTML+CSS,那么可能就到此结束了,but还有神奇的JS呢,请看回流和重绘。
回流(Reflow)和重绘(Repaint)
如果这个时候我写了用JS操作了DOM,将网页的所有元素设置float:left,那么问题来了,4、5的工作白干了,推翻从新再来。如果将所有元素的颜色改变了(并没有改变结构),比如color:red,还好还好,5的工作白干,推翻重来。可以想象一下,你辛辛苦苦加班一个月终于完成工作,产品经理来了一句:“好像要改一下需求…”
所以,尽可能少操作DOM,提升网页的性能。
【question】再回到最开始的这个问题,为什么获取到的DIV高度有问题?
刚开始一帆风顺,进行到第五步之后,又回到了第四步,此时如果是块级元素,就会设置好宽高,不存在任何问题。但如果是图片,此时是无法得知高度的(行内元素),只有等待第五步绘制以后再能确定高度。而图片的绘制需要时间,在尚未绘制完成的时候,获取到的高度则会出现问题。合理的解决方案是使用setTimeout延时获取div的高度。代码如下:
<div class="bgImg"></div>
创建渲染树后,接下来正式开工,确定各个元素的位置,包括元素在视图中的位置以及自身的大小,将其安置在浏览器的正确位置。
5. 绘制(Painting)
这个阶段,浏览器会遍历呈现树,并调用呈现器的“paint”方法,将前期所有的工作结合到一起,将网页的内容呈现出来。如果网页只是HTML+CSS,那么可能就到此结束了,but还有神奇的JS呢,请看回流和重绘。
回流(Reflow)和重绘(Repaint)
如果这个时候我写了用JS操作了DOM,将网页的所有元素设置float:left,那么问题来了,4、5的工作白干了,推翻从新再来。如果将所有元素的颜色改变了(并没有改变结构),比如color:red,还好还好,5的工作白干,推翻重来。可以想象一下,你辛辛苦苦加班一个月终于完成工作,产品经理来了一句:“好像要改一下需求…”
所以,尽可能少操作DOM,提升网页的性能。
【question】再回到最开始的这个问题,为什么获取到的DIV高度有问题?
刚开始一帆风顺,进行到第五步之后,又回到了第四步,此时如果是块级元素,就会设置好宽高,不存在任何问题。但如果是图片,此时是无法得知高度的(行内元素),只有等待第五步绘制以后再能确定高度。而图片的绘制需要时间,在尚未绘制完成的时候,获取到的高度则会出现问题。合理的解决方案是使用setTimeout延时获取div的高度。代码如下:
<div class="bgImg"></div>
<script>
var odiv = document.getElementById(‘bgImg‘);
odiv.innerHTML = ‘<img src="test.jpg">‘
setTimeout(() =>
var oHeight = odiv.scrollHeight;
console.log(oHeight);
,100)
</script>
var odiv = document.getElementById(‘bgImg‘);
odiv.innerHTML = ‘<img src="test.jpg">‘
setTimeout(() =>
var oHeight = odiv.scrollHeight;
console.log(oHeight);
,100)
</script>
123456789101112
想要更详细的了解可以去《浏览器工作原理:新式网络浏览器幕后揭秘》
---------------------
版权声明:本文为CSDN博主「Feb~」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lilele0227/article/details/85866986
想要更详细的了解可以去《浏览器工作原理:新式网络浏览器幕后揭秘》
---------------------
版权声明:本文为CSDN博主「Feb~」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lilele0227/article/details/85866986
以上是关于浏览器渲染页面过程的主要内容,如果未能解决你的问题,请参考以下文章