深圳市博士通科技有限公司

浏览器从输入URL到渲染完页面的整个过程是怎么样的?

2020/11/2 10:31:37   阅读:2083    发布者:2083

      

   浏览器的主要功能是将用户选择的web资源呈现出来,它从服务器请求资源,并将得到的资源(HTML,PDF,image等等)显示在浏览器窗口。那么从用户敲入URL到完整渲染出来,经历了什么过程呢?也就是说整个浏览器的工作流程是怎样的呢?

整个过程大致如下:


       1. 输入URL,浏览器根据域名寻找IP地址
       2. 浏览器发送一个HTTP请求给服务器,如果服务器返回以301之类的重定向,浏览器根据相应头中的location再次发送请求
       3. 服务器接受请求,处理请求生成html代码,返回给浏览器,这时的html页面代码可能是经过压缩的
       4. 浏览器接收服务器响应结果,如果有压缩则首先进行解压处理
       5. 浏览器开始显示HTML 

       6. 浏览器发送请求,以获取嵌入在HTML中的对象。在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。


这时,浏览器会发送一个获取请求来重新获得这些文件——包括CSS/JS/图片等资源,这些资源的地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等…

 那么,一个页面,究竟是如何从我们输入一个网址到最后完整的呈现在我们面前的呢?还需要了解一下浏览器是如何渲染的。
首先是用户输入url,浏览器通过DNS查询要访问页面的IP,查询到后,浏览器会替用户去向这个IP地址发送请求拉取html文件,浏览器会派GUI线程去解析加载回来的html文件

html解析过程:01机器码-》charter字符-》tokens令牌-》node节点-》dom树


解析CSS,构建CSSOM
有了骨骼以后,接下来就是确定长相了,这是CSS要做的事情。和解析HTML类似,CSS解析各种样式信息,生成网页的“外观”。但是有个问题,CSSA(class选择器)说,我喜欢蓝色,我家网页的所有文字都要是蓝色。CSSB(id选择器)就不乐意了,凭啥啊,我喜欢红色,我家的标题必须是红色。由于id选择器是亲生的,那就标题是红色的吧,于是不同选择器就有了不同的权重。最后生成CSSOM

因为浏览器解析文档,如果遇到请求外部资源时,如图像,iconfont,JS等。浏览器将下载该资源。请求过程是异步的,并不会影响HTML文档进行加载,当遇到 <script>标签的时候,会立即解析脚本,停止解析文档(因为JS可以操作DOM和CSS,可能会改动DOM和CSS,所以继续解析会造成浪费)。如果脚本是外部的,会等待脚本下载完毕,再继续解析文档。所以常见的做法是将js放到页脚部分。

      

构建Render Tree(呈现树)


骨骼和长相都有了,那就组合到一起呗,DOM和CSSOM根据一定的规则组合起来生成了Render Tree。

 布局(Layout)


创建渲染树后,接下来正式开工,确定各个元素的位置,包括元素在视图中的位置以及自身的大小,将其安置在浏览器的正确位置。


绘制(Painting)


这个阶段,浏览器会遍历呈现树,并调用呈现器的“paint”方法,将前期所有的工作结合到一起,将网页的内容呈现出来。如果网页只是HTML+CSS,那么可能就到此结束了,but还有神奇的JS呢,请看回流和重绘。

回流(Reflow)和重绘(Repaint)


如果这个时候我写了用JS操作了DOM,将网页的所有元素设置float:left,那么问题来了,上面两步的工作白干了,推翻从新再来。如果将所有元素的颜色改变了(并没有改变结构),比如color:red,还好还好,上面一步的工作白干,推翻重来。可以想象一下,你辛辛苦苦加班一个月终于完成工作,产品经理来了一句:“好像要改一下需求…”
页面在首次加载时必然会经历reflow和repaint。reflow和repaint过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repaint。

所以,尽可能少操作DOM,提升网页的性能。

总结一下:


       1. 解析HTML
       2. 构建DOM树
       3. DOM树与CSS样式进行附着构造呈现树(render树)
       4. 布局
       5. 绘制
      上述这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。