面试经典题——URL加载一、涉及的基础知识点:1、计算机网络五层Intel协议栈:应用层(dns、http):DNS解析成IP,发送http请求;传输层(tcp、udp):三向握手和四向wave方式建立tcp连接;网络层(IP、ARP):IP寻址;数据链路层(PPP):将请求数据封装成帧;物理层:使用物理媒体传输比特流(传输时通过双绞线、电磁波等)OIS七层框架:多了两层,即会话层(处理两个通信系统中交换的信息的表示)和表示层(管理不同用户和进程之间的对话)。get和post的区别:get生成一个tcp数据包,post生成两个get请求时,headers和data数据会一起发送;当有post请求时,浏览器先发送headers,服务器100继续,浏览器发送数据。DNS查询获取IP请求信息:首先查看域名的本地DNS缓存,里面存放着电脑最近检索到的信息,如果电脑不知道答案,那么就需要进行DNS查询来寻找答案;询问递归DNS服务器:如果信息不是本地存储,而是联系您的ISP(互联网提供商)的递归DNS服务器;这些专用计算机为您执行DNS查找工作;递归服务器有自己的缓存,所以查找过程通常在这里完成,并将信息返回给用户;询问根名称服务器,如果递归服务器没有回答,他们将查询根名称服务器;根名称服务器是一台充当DNS电话接线员的计算机,他们不知道答案,但我们的疑问可以转给知道在哪里可以找到答案的人。询问TLD域名服务器:根域名服务器会看请求的第一部分,按照从右到左的顺序,从www.dyn.com找到.com,将请求指向顶级域名服务器(TLD).com对应.com;每个TLD,比如(.com,.org,.us)都有自己的顶级域名服务器,这些服务器没有我们需要的信息,但是可以直接把我们引导到有信息的服务器。询问权威DNS服务器TLD名称服务器将继续检查请求(dyn)www.dyn.com的下一部分,并将查询定向到负责该特定域名的服务器;这些权威服务器将负责了解特定域的所有信息,并将信息存储在DNS记录中。检索记录:-递归服务器从权威服务器检索dyn.com的记录,并将记录存储在本地缓存中;如果其他人请求dyn.com的主机记录,递归服务器已经有了答案,不需要再做查找;所有记录都有一个到期日期,之后递归服务器将需要请求记录的新副本以确保信息不会过时。接收答案:有了答案,递归服务器将记录返回给您的计算机,您的计算机将记录存储在缓存中,从记录中读取IP地址,并将此信息传递给浏览器;浏览器然后可以与服务器建立连接。TCPIP请求http的本质是TCPIP请求;需要经过3次握手建立连接,4次挥手断开连接;TCP将http长报文分成短报文,通过三次握手与服务器建立连接,进行可靠传输。三向握手:客户端:你是XXX服务器吗?服务器:我是XXX服务器,你是客户端吗?客服:是的,我是客户。连接成功后,接下来就可以进行正式的数据传输了。挥手四次断开主动方:我已经关闭了给你发送信息的通道,只能被动接收信息;被动方:收到通道关闭的消息;被动方:我现在也关闭了到你这边的通道发送信息的通道主动方:左边收到信息,连接断开,然后双方无法通信。TCP/IP并发限制:浏览器对同一域名下的并发TCP连接有限制(2-10等),而在http1.0中,一次资源下载往往需要一次tcp/ip请求二、浏览器机制(一)概念进程和线程的进程是CPU资源分配的最小单位,可以拥有资源并独立运行的最小单位;线程是CPU调度的最小单位,线程是基于进程的程序运行单位,一个进程可以有多个线程;通俗地说:一个进程就是一个工厂,工厂有自己独立的资源。相互独立->进程相互独立,线程是工厂里的工人,多个工人可以合作完成任务,工厂里有一个或多个工人,工人共享空间。(2)多进程浏览器浏览器是多进程的,有一个master进程,每个tab页都会打开一个进程(在某些情况下,由于优化策略会合并多个tabs)浏览器的主进程:BrowserProcess:浏览器的主进程,负责协调和主控,只有一个,功能:负责浏览器界面的显示,与用户交互(如前进,后退等),负责管理每个页面,创建和销毁其他进程;Renderer进程获取到的内存中的Bitmap绘制到用户界面,用于网络资源管理和下载等第三方插件进程:每一种插件对应一个进程,只有在插件运行时创建-in被使用;GPU进程:最多一个,用于3D绘图等;浏览器渲染进程(Renderer进程、浏览器内核、内部多线程):默认不打开标签页,会启动一个Renderer进程;负责页面渲染、脚本执行和事件处理。多进程浏览器的优点可以避免单个页面崩溃影响整个浏览器;避免第三方插件崩溃影响整个浏览器。多进程可以充分利用多核的优势;方便使用沙箱模型隔离插件等进程,提高浏览器稳定性。简单理解:如果浏览器是单进程,那么如果某个标签页或者第三方插件崩溃,会导致整个浏览器崩溃,体验极差,但是多进程的内存消耗会更大,这是一种空间换时间的交易。浏览器内核(渲染进程)在浏览器渲染进程内部是多线程的,包括主要线程:1.GUI渲染线程:(1)负责渲染浏览器界面,解析HTML、CSS,构建DOM树和RenderObject树,布局绘图等;(2)当界面需要重绘(Repaint)或某些操作导致回流(reflow)时,会执行该线程;注意:GUI渲染线程和JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会存入一个队列,当JS引擎空闲时立即执行。2、JS引擎线程:JS核心,负责处理JavaScript脚本程序(V8引擎)负责解析JavaScript脚本并运行代码;JS引擎一直等待任务队列中任务的到来,然后对其进行处理,在一个标签页(渲染进程)中任何时候,只有一个JS线程在运行JS程序;注意:由于GUI渲染线程和JS引擎线程是互斥的,如果JS程序运行时间过长,会造成页面渲染不连贯,导致页面渲染和加载阻塞;3.事件触发线程:属于浏览器,不属于JS引擎,用于控制事件循环;当JS引擎执行setTimeOut等代码块时(也可以来自于浏览器内核的其他线程,比如鼠标点击事件、AJAX异步请求等),相应的任务就会被添加到事件线程中;当相应的事件满足触发条件并被触发时,线程会将事件添加到JSpending队列的尾部,等待JS引擎的处理;注意:由于JS的单线程关系,这些pending队列中的事件不得不排队等待JS引擎处理(JS引擎只有在空闲的时候才会执行)。4、定时触发线程:setTimeOut和setInterval所在的线程;浏览器的计时计数器是不会被JavaScript引擎统计的(因为JavaScript是单线程的,如果被阻塞会影响计时的准确性)所以通过一个单独的线程来计时并触发计时(计时结束后,空闲时加入事件队列等待JS引擎执行)5.异步http请求线程:XMLHttpRequest连接后,通过浏览器开启一个新的线程请求,会检测状态变化,如果设置了回调函数,异步线程会产生一个状态改变事件,将这个回调放入事件队列中,然后由JavaScript引擎执行。1、一个页面从输入URL到加载显示发生了什么?简易版:浏览器将请求的URL提交给DNS域名解析,找到真实IP,向服务器发起请求;服务器后台处理完成后返回数据,浏览器接收文件(HTML、CSS、JavaScript等);解析加载的资源(HTML、CSS、JavaScript等),构建相应的内部数据结构(DOM树、CSS树、渲染树等);加载已解析的资源文件,呈现页面,然后完成。详细版:首先浏览器开启一个线程处理请求,并对URL进行分析判断。如果是http协议,则按照Web方式处理;其次,浏览器会对URL进行解析,一般包括(协议头、主机域名或IP地址)、端口号、请求路径、查询参数、hash等),然后启动网络线程发送一个完整的http要求;当然,我们输入的URL是服务器域名,然后DNS需要通过域名查询到对应的IP;DNSfirst会查看浏览器的DNS缓存,如果没有则查询电脑本地的DNS缓存,并询问递归的DNS服务器(也就是网络提供商,一般这个服务器都会有自己的缓存,所以IP查询是一般在这里完成),如果没有缓存,那么就需要指向对应的权威DNS服务器,通过根域名和TLD域名服务器检索记录,并缓存到递归服务器,再递归服务器返回记录到本地。有了IP地址,此时网络层会通过IP地址对应的服务器的物理地址找到服务器地址,客户端可以在网络上通过三次握手与服务器建立tcpip连接传输层。连接建立后,网络数据链路层将数据打包成帧;最后,物理层使用物理介质进行传输;当它到达服务器时,它会以相反的方式逐层恢复数据;当请求到达后台服务器时,一般会有统一的校验,比如安全校验、跨域校验等,校验不通过直接返回相应的http报文。验证通过后,会进入后台代码。这时程序接收到请求,然后执行相应的操作(如查询数据库等);如果浏览器访问过,并且缓存中有对应的资源,则与服务器的最后修改时间进行比较,如果一致则返回304,告诉浏览器可以使用本地缓存;前端浏览器收到成功响应信息后,开始下载已下载的网页,交给浏览器内核(渲染进程)处理:根据顶部定义的DTD类型,执行相应的解析方法;渲染过程内部是多线程的,网页的解析会交给内部的GUI渲染线程处理;首先渲染线程中的HTML解释器将HTML网页和资源从字节流解释并转换为字符流;然后通过词法分析器将字符流解释成词;然后通过词法分析器根据词建立节点;最后通过这些节点构建DOM树;在这个过程中,如果遇到的DOM节点是JavaScript代码,就会调用JavaScript引擎解释并执行JavaScript代码。这时候JavaScript引擎和GUI渲染线程是互斥的,GUI渲染线程会被阻塞。Suspend,渲染进程停止;如果在JavaScript代码运行过程中修改了DOM树,则需要重新构建DOM;如果节点需要依赖其他资源,比如(图片,CSS等),网络模块的资源会调用loader来加载,但是它们是异步的,不会阻塞当前DOM树的构建;如果遇到JavaScript资源URL(未标记为异步),则需要停止当前DOM的构建,直到JavaScript资源加载完毕并被JavaScript引擎执行后继续构建DOM;对于CSS,CSS解释器会将CSS文件解释成内部表示结构,生成CSS规则树;然后合并CSS规则树和DOM树生成渲染树;最后对渲染树进行布局和绘制,并将结果通过IO线程传递给Browser控制进程进行显示。
