在前端面试过程中经常会遇到这个问题:从浏览器输入url到显示界面发生了什么?
这个问题其实考验的是一个前端工程师是否了解浏览器的运行原理和html、css、js的运行原理。
以下将做出详细解答,图片来源自B站link
有兴趣的可以去B站看一遍视频,将会有更深的理解。本人在博客中只是做一个总结记录。
浏览器结构图:
- 用户界面用于展示除标签页窗口外的其他用户界面内容
- 渲染引擎负责渲染用户请求的页面内容
- 在用户界面和渲染引擎有一个浏览器引擎,用于在用户界面和渲染引擎之间传递数据
- 渲染引擎下许多小模块,例如负责网络请求的网络模块,用于解析和执行js的js解释器
- 还有数据持久层,帮助浏览器存储各种数据,比如cookie等
1.在UI线程会启动一个网络线程来请求DNS请求进行域名解析,接着开始连接服务器获取数据,接收到返回数据后,网络线程会向UI线程传送数据,UI线程会创建一个渲染器进程来渲染页面,浏览器进程通过IPC管道将数据传递给渲染器进程正式进入渲染流程。渲染器进程接收到的数据也就是html,渲染器进程就是把html,css,js,image等资源渲染成用户可以交互的web页面,渲染器进程的主线程将html进行解析,构造DOM数据结构。
注意:图片和css不会影响html的解析,但是当Html解析过程遇到script标签将停止html解析流程,转过去加载js。
2.当Html解析完成后,可以得到一个DOM Tree。主线程再解析CSS来确定每个DOM结点的计算样式,即使没有自定义的CSS样式,浏览器会有自己的默认的样式表。
3.接下来需要知道的是结点需要放在页面上的哪个位子,也就是结点的坐标以及该结点需要占用多大的区域。这个阶段就是layout布局。主线程通过遍历dom和计算好的样式来生成layout tree,layoutTree每个结点都记录了x,y坐标和边框尺寸。
注意:设置了display:none的结点不会出现在layoutTree上。
而在before伪类中添加了content值的元素,content里的内容会出现在layoutTree上,不会出现在dom tree上。
4.通过遍历layoutTree生成绘制顺序表(这个阶段被称为绘制),根据绘制顺序表和layoutTree再生成layerTree(图层树)
**总结:**浏览器发起一个网络线程来请求DNS来进行域名解析,接着连接服务器进行数据请求,网络线程拿到数据后再将数据传回到浏览器的UI线程,先进行的是HTML解析,生成的是DOMTree,然后再解析CSS来确定DOM每个结点的样式,即使没有样式,浏览器内部也会有自己内部的默认样式。再通过遍历DOMTree和解析好的样式生成layoutTree上有每个结点的坐标和边框尺寸,再通过遍历layoutTree来生成绘制顺序表来确定在页面上绘制的一个顺序。最后生成layerTree发送给合成器线程,合成器线程根据分图层,分成更小的图块发给栅格线程,栅格线程再进行栅格化,生成图表信息传回给合成器线程。根据这些信息,合成器线程合成了一个合成器帧传给浏览器进程,浏览器进程再传到GPU进行渲染,然后就展示到屏幕上了。