这是一个经久不衰的面试题,整理一下。
浏览器
浏览器是一个多进程的架构。
主进程:主要适用于界面的显示,用户的交互,子进程管理。
渲染进程:将HTML,css,JS转换成页面,V8引擎以及排版用的Blink引擎都是在渲染进程中。
GPU进程:绘制UI界面。
网络进程:负责网络资源的加载。
插件进程等......进程之间的通信是通过ipc来通信。
主进程中:在输入一个网址后,开始处理输入信息,开始导航,进入网络进程,浏览器访问的应该是IP地址,那么首先会输入的域名转换为ip 地址。
DNS域名解析:
有很多网页都跟着.com .cn等,因为都隶属于这些域名来管理,而这些.com 是由.来进行划分和管理的,最后都是由根统一管理的,但也没有必要写.root来表示,以下就是域名结构树。
这个根是由一群服务器组成的,称为根域名服务器,在它的下面,包括.com .cn等,称为顶级域名服务器,它们会管理各自的域名服务器,比如bilibili,QQ等,它们称作权威域名服务器,然后管理各自的主机。
所以在输入网址后,浏览器先查看缓存中是否含有对应的ip 记录,同时查看主机本地文件里是否有文件记录,如果有记录那么就不用解析了,如果没有,浏览器进行域名解析,向DNS服务器发送请求,需要调用解析器,通过域名获取ip地址。
请求和响应
通过DNS解析以后,获取到了相应的站点,会通过safeBrowsing来检查站点是否是恶意站点,如果是则展示为恶意站点,会阻止访问。
计算机网络模型有7层的osi模型,还有5层以及TCP/IP的4层的模型,浏览器通过http协议发送请求,那么首先在应用层利用DNS服务器解析域名,获得ip地址,通过http或者https封装,包括请求头等信息。
接下来数据来到传输层:再次将上层内容封装,封装为TCP/UDP报文;
网络层:再次进行封装为IP报文;
数据链路层:将IP报文进行分组形成帧;
物理层:帧封装成0/1信号,就是bit单位,再进行传输;
然后就是网线传输
到了服务端其实就是一套逆行:bit->帧->IP报文,之后服务器再进行响应,流程与发送请求类似。
到了浏览器,获取到了返回的数据,则开始渲染页面。
一切准备就绪后,网络进程会告知UI进程,UI进程会开启一个渲染器进程来渲染页面,浏览器进程通过IPC管道将数据传递给渲染器进程。
渲染进程
一般请求获取到的数据都是HTML文件,相当于网页的框架结构,不过一开始获取到的是字节形式的HTML文件,通过解析转化得到字符代码,然后再到tokens符号标签,最后变为节点对象,讲这些节点对象连在一起形成文本对象模型,也就是dom,dom就是浏览器自己的语言,每个节点对象项连,形成父子关系。
与此同时css样式会以link标签的形式引入,在渲染HTML文件的过程中,遇到link标签,会向服务器请求css文件,具体解析与HTML相同,最后节点会结合为css对象模型,也就是cssom,dom和cssom都已经有了,基本也就完成了,两者结合就是渲染树,渲染树的任务就是匹配dom和cssom的节点,并且捕获可见内容。
在渲染树构造完成之后,页面也是不能被马上渲染的,还需要获取渲染树的结构,节点位置和大小来进行布局,是根据盒子模型来进行,每个元素都用一个盒子来表示,然后这些盒子在页面上进行排列和嵌套,生成layout-tree,在布局以后,浏览器就可以安排页面的绘制了,为了保证展示正确的层级,渲染进程的主线程会遍历layout-tree,创建一个绘制记录表,该表记录了绘制的顺序(z-index),然后渲染进程的主线程将数据传递给合成器线程,合成器线程将每个图层栅格化,由于一层可能像页面的整个长度一样大,因此合成器线程会将他们切分为很多图块,然后将每个图块发送给栅格化线程,栅格化线程栅格化每个图块,并将他们存储在GPU内存中,当栅格化完成后,合成器线程将收集称为"draw quads"的图块信息,信息中记录了图块在内存的位置,以及在页面需要绘制的位置,根据这些信息,合成器线程生成了一个合成器帧,通过IPC进程传递给浏览器进程,接着浏览器进程将合成器帧传入GPU,然后GPU渲染展示到屏幕上,当滚动滚轮,都会生成一个新的合成器帧,新的帧再传给GPU,再次渲染到屏幕上,这样就以像素的形式绘制在页面,页面就呈现出来了,当我们改变一个元素的尺寸位置属性时,会重新进行样式计算,布局绘制以及后面的流程,这种行为叫做重排(回流),如果改变了元素的颜色,不会重新触发布局,但还是会触发样式计算和绘制,这个就是重绘。
但是在实际情况中,我们还会遇到script标签,还会向服务器请求js文件,如果先返回并解析完成js文件是会发生堵塞的,所以必须等到Cssom构建完成后才执行js文件,而且js可以改变css样式。cssom构建就是渲染中一个重要的阻塞原因,其实dom也会,但是dom可以部分解析,cssom不可以。cssom的构建和js文件的请求和解析是可以同时进行的,等cssom结束构建后,就可以执行js文件。
js会阻塞HTML的解析,因为js既可以操作dom,又可以操作cssom,如果不等js下载解析执行完以后再构建dom,页面有些内容会可能会出现了又消失,所以不管是行内js代码还是外部js代码,都会让HTML的解析停止下来,虽然dom可以部分解析,但对于网页来说,就相当于阻塞了第一次的渲染,js执行完之前,页面什么都没有,执行完以后就都正常了,形成渲染树,进行布局,绘制等。