流程图这道题貌似没什么问题,无非就是HTTP请求到浏览器渲染,但是要讲的东西很多。我认为它的执行顺序是,用户输入——开始导航——HTTP请求——浏览器渲染。其中,用户输入、开始导航、浏览器渲染是浏览器的知识点,HTTP请求是HTTP的知识点。以下是从输入url到看到页面的整个流程图原文地址:https://s2.loli.net/2022/04/2...前言在理解“开始导航”之前,你需要知道浏览器架构。简单来说,现代浏览器由1个浏览器主进程、1个GPU进程,以及多个渲染进程、多个插件进程、网络进程、音频进程、存储进程组成。这样描述的图片显示,浏览器的主进程包括UI线程、网络线程和存储线程,这与李冰的观点不同。谁将占上风?从时间上看,李冰的专栏是2019年写的,《现代浏览器内部解密》是2018年写的。站在2022年的背景下,现代浏览器、UI、网络、存储等都升级为进程,而不是Thread用户输入在浏览器主进程中,当用户在地址栏中输入字符串时,地址栏会判断输入的关键字是搜索内容还是请求的URL。如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,用搜索关键词合成一个新的URL。比如在chrome中搜索长泽雅美。如果输入的内容符合URL规则,比如输入azhubaby.com,那么地址栏就会把这个内容按照规则添加到协议合成的URL中,例如https://azhubaby.com当用户输入关键字并回车时,表示当前页面将被替换为新页面。这时候浏览器中有一个API——beforeunload,可以让页面在离开前触发是否确认对话框。这里使用这个API可以让浏览器停止导航//离开页面前监听事件window.addEventListener('beforeunload',(event)=>{event.preventDefault();event.returnValue='';})可以在这里查看beforeunload的演示。从浏览器架构划分来看,当用户输入字符串时,就是UI进程(旧浏览器是主要的浏览器进程)。当导航开始时,当按下回车键时,UI进程将命令的传输传递给网络进程。网络进程在接受请求命令之前,会先检查本地缓存中是否有缓存。如果资源被缓存,则直接将资源返回给浏览器进程;如果在缓存中没有找到该资源,则正式进入HTTP请求阶段。关于HTTP缓存的知识可以看这篇文章——面试官:HTTP缓存HTTP请求之前,我写了一篇TCP/IP协议和网络分层模型的文章,里面描述了TCP/IP网络分层协议。它就像积木一样。每一层都需要下一层的支持。我们的HTTP请求就是它的HTTP协议的应用,需要先连接传输层(TCP)和下层的网络互连层(IP)。IP从哪里来?通过DNS,将域名和IP进行映射。我们可以用反向的方法来明确“路由”:HTTP请求——HTTP协议连接——TCP协议连接——IP协议连接——需要知道IP——DNS做域名/IP映射,所以第一步进入HTTP请求是DNS解析DNS解析这里不做过多的DNS概述,简单来说,它的作用就是将IP地址替换成域名,符合人的记忆。输入du.azhubaby.com,即IP地址为47.102.152.19。您可以在命令行中ping一个域名来验证结果。HTTP请求前的第一步是判断DNS中是否有缓存。如果是,直接返回IP地址;如果没有,则进行DNS解析,并将结果IP缓存到DNS中。获取到IP地址后,IP层连接成功,接下来就是TCP传输层TCP连接,这里取决于HTTP协议的版本。如果是HTTP/1.1,需要考虑TCP队列是否已满,因为HTTP/1.1允许一个域名最多有6个TCP连接,如果过多,会在等待TCP中排队队列;如果是HTTP/2,那还好,这里允许TCP并发。在考虑如果协议是HTTPS协议,需要建立真正的TCP连接比如TLS连接,想到网红面试题:三向握手,四向挥手三向握手,四向handshake为什么是三次握手和四次握手,因为只有这样双方(客户端和服务器)才能知道对方的接收和发送能力。步骤是:client提出建立连接,发送clientseq:seq=client_isnserver收到消息后返回ack=client_isn+1和serverseq:seq=server_isnclient收到后返回ack=server_isn+1它,可以理解为男女关系的确认。男方女方想结婚,怎么办?先见家长,得到家长的认可。以前听过这样一句话:没有父母祝福的婚姻是不幸福的(当然也有不见父母直接结婚的,但不是主流)。seq=男方的诚意,女方家收到见面礼后会回(给男方)红包ack=我们认可你,女方去男方家也会带上见面礼seq:seq=诚意女方的男方家收到见面礼后会回(给女方)红包ack=server_isn+1这叫确认关系。所以你要来回三趟,双方一定要知道对方和自己的诚意。那么什么是四挥手呢?断开前需要四次挥手为什么要有四次挥手?主要是保证双方都知道对方断开了。具体步骤是:客户端第一次向服务器发送消息,告诉它需要断开连接。服务器在收到之前所有的HTTP请求后,需要等待一段时间再断开连接。服务端确认所有的HTTP请求都收到了,主动给客户端发消息:我这边的请求都处理完了,我也可以断开连接了。客户端收到这个请求后,返回消息告诉服务器:我知道,断开连接,主要是确认双方的收发能力是否正常,并为后面的可靠传输制定自己的初始化序号准备可以理解为夫妻要分手。女方提出分手,说你对我不好,我要分手。男方认为需求合理,同意分手,但分手前,联系方式,合影,各种乱七八糟的东西,你必须搞清楚。和男方分手后,他主动给女方发信息,说什么都在这里处理了。从此以后,你就是你,我就是我。我们可以分手了。于是乎,他们破碎,分离程序完成。具体详细信息请看猿人谷采访者。别叫我握三下手,挥四下手。一句话:发送HTTP请求,TCP连接已经建立。现在HTTP请求正式发送了。HTTP报文内容、请求头、响应头、请求方法、状态码等知识点首先,HTTP报文结构由起始行+报头+空行+实体组成,简单来说就是报头+正文,HTTP的消息可以没有正文(get方法),但必须有标题。请求头由请求行+头域组成,响应头由状态行+头域组成。请求行有三部分:请求方法、请求目标和版本号,例如GET/HTTP/1.1状态行也有三部分:版本号、状态码和原因字符串例如,HTTP/1.1200OK在浏览器中,打开F12,在NetWork中的任何请求中,你都会在这里看到这样的结构我们也经常会遇到一些衍生问题,比如GET和POST请求方式的区别,HTTP状态码等等GET和POST请求方式的区别从缓存的角度来说,GET会缓存,POST不会缓存。从参数的角度看,GET在“?”之后传递key=value中的参数安全,因为URL是可见的;POST比GET更安全从编码的角度来说,GET只接受ASCII字符,汉字发送到服务器可能会出现乱码;POST支持标准字符集,可以正确传输中文。从数据长度限制来看,GET一般受URL长度限制(URL最大长度为2048个字符),POST则不受HTTP状态码限制。RFC标准将状态码分为五类,用编号的第一位表示分类,0~99不用。代码的实际可用范围大大缩小,从000~999变成了100~599。这五类的具体含义是:1××:提示信息,表示当前协议处理处于中间状态,还需要进行后续操作;2××:成功,消息已正确接收和处理;3××:重定向,资源位置发生变化,客户端需要重新发送请求;4××:客户端错误,请求报文错误,服务端无法处理;5××:服务器错误,服务器处理请求时发生内部错误。RFC标准中目前有41个状态码101-SwitchingProtocols,客户端使用Upgrade头字段200-请求成功204-无内容,服务端成功处理了请求,但没有返回任何内容。206-一般用于断点续传,或者视频文件等大文件的加载301-永久重定向302-临时重定向304-未修改的协商缓存,返回缓存中的数据。没有通常跳转的意思,但可以理解为重定向到缓存文件(即缓存重定向)400-请求中语法错误401-未经授权403-服务器收到请求,但拒绝提供服务,即资源不可用Use404-请求的资源找不到408RequestTimeout-请求超时414-请求URI过长(如图1新浪常有)500-内部服务器错误501-尚未实现:服务器没有请求功能502-网关错误503-服务器不可用使用,主动使用503响应请求或者在Nginx中设置限速。如果超过限速,将返回503504-网关超时。这里是对304的解释,当请求头If-Modified-Since或If-None-Match判断修改时间是否一致(或者唯一标识是否一致),如果一致则返回304,并使用本地缓存中浏览器内存;如果不一致,则表示需要更新,继续请求资源返回给客户端,并带上Last-Modified或ETag请求方法HTTP/1.1规定八种方法,必须全部大写GET:获取资源,可以理解为读取或者下载数据。只有GET请求才有缓存效果HEAD:获取资源的元信息POST:类似于资源提交数据,相当于写入或上传数据PUT:类似于POSTDELETE:删除资源CONNECT:建立特殊的连接隧道OPTIONS:列表availableresources实现方法TRACE:Tracingrequest-responsetransmissionpathBrowserrendering当HTTP请求完成后,断开TCP连接,将资源返回给客户端(浏览器)。这时候浏览器就得判断和打开的网站是不是同一个站点了。因为如果是同一个站点,可以使用同一个站点的渲染进程来渲染页面。如果没有,浏览器会开启一个新的渲染进程来解析资源浏览器。渲染的大致流程如下图所示:我们可以将页面渲染分为三个步骤:解析HTML解析成DOM树,CSS解析成CSS规则树,JavaScript使用DOMAPI和CSSOMAPI来操作DOMTree和CSSRuleTree渲染浏览器引擎通过DOMTree和CSSRuleTree(渲染树)构建RenderingTree,其中大量的回流(Reflow)和重绘(Repaint)回流和重绘reflow:表示组件的几何尺寸发生了变化,并且需要重新验证和计算RenderTreeredraw:部分屏幕需要重绘比如某个CSS的背景色发生了变化,但是组件的几何尺寸没有发生变化。回流的成本比重绘的成本大。最后通过操作系统(浏览器)的NativeGUIAPI绘制,导致重绘和回流问题。提高性能的方法之一是减少浏览器的渲染时间。优化点之一是减少重绘和回流。减少回流和重绘的方法不是一一修改DOM样式。与其这样做,不如预先定义CSS类,然后修改DOM的样式。使DOM“离线”并修改它。使用documentFragment对象来操作内存中的DOM。首先给DOM显示:none(有Reflow),然后你想怎么改就怎么改,然后显示。Clonea把DOM节点放到内存中,然后想怎么改就怎么改。修改好后,和网上的交换一下。不要将DOM节点的属性值作为循环变量放在循环中,否则会导致大量的读写。尽量修改节点的属性,修改下层DOM。不要使用表格布局导致回流属性:width,height,padding,margin,border,position,top,left,bottom,right,float,clear,text-align,vertical-align,line-height,font-weight,font-size,font-family,overflow,white-space引起重绘的属性:color,border-style,border-radius,text-decoration,box-s记住关于阴影、轮廓和背景的一件事。回流与几何尺寸有关,重绘与尺寸无关。从输入url到看到页面的整个过程就结束了。总结一下,这道题可以出很多题,可以从一道题来考。受访者对HTTP和浏览器的相关知识,正所谓“大鹏怒飞,其翼如云垂天;水打三千里,青天九万尺;好风强送我去青云。”这道题之所以能成为经典题,不是没有原因的。笔者在这里做一个总结,将这道题可以推导出来的知识点一一列举出来。等你想想浏览器,浏览器的架构是由什么组成的呢?浏览器主进程、GPU进程、多渲染进程、多插件进程、网络进程、音频进程、存储进程等渲染进程有哪些?GUI渲染线程、JS引擎线程、事件触发线程、网络异步线程、定时器线程进程和线程有什么区别?进程是应用程序创建的实例,线程依赖于进程。它是计算机的最小操作单元。浏览器渲染渲染过程?解析、渲染、绘制重绘和回流的区别重绘和回流属性如何减少重绘和回流,提高渲染性能HTTP方面HTTP缓存强缓存HTTP/1.1Cache-ControlHTTP/1.0ExpiresCache-Control>ExpiresNegotiationcachingHTTP/1.1ETag/If-None-MatchHTTP/1.0Last-Modified/If-Modified-Since精度:ETag>Last-Modified性能:Last-Modified>ETagTCP/IP连接的三次握手和四次握手网络层面的性能优化HTTP的方法/1.1HTTP/2的方法HTTP/3的方法每个阶段采用的性能优化是不同的。浏览器内部工作原理(附详细流程图)前端应该了解的浏览器工作原理
