精华内容
下载资源
问答
  • 输入URL到页面展示的详细过程

    万次阅读 多人点赞 2018-03-30 14:00:43
    其实从输入URL到页面展示在我们眼前所经历的过程其实还是非常复杂的,牵扯的知识点也是非常的庞杂。其中很多知识都会有专门的学科去研究,所以这里只是简单地概括一下大致流程:1、输入网址2、DNS解析3、建立tcp...

    其实从输入URL到页面展示在我们眼前所经历的过程其实还是非常复杂的,牵扯到的知识点也是非常的庞杂。其中很多知识都会有专门的学科去研究,所以这里只是简单地概括一下大致流程:

    • 1、输入网址
    • 2、DNS解析
    • 3、建立tcp连接
    • 4、客户端发送HTPP请求
    • 5、服务器处理请求 
    • 6、服务器响应请求
    • 7、浏览器展示HTML
    • 8、浏览器发送请求获取其他在HTML中的资源。

    下面是转载自https://www.cnblogs.com/xianyulaodi/p/6547807.html的一篇博文,讲解的感觉还不错。


    1、输入地址

        当我们开始在浏览器中输入网址的时候,浏览器其实就已经在智能的匹配可能得 url 了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url,然后给出智能提示,让你可以补全url地址。对于 google的chrome 的浏览器,他甚至会直接从缓存中把网页展示出来,就是说,你还没有按下 enter,页面就出来了。

    2、浏览器查找域名的 IP 地址  

      1、请求一旦发起,浏览器首先要做的事情就是解析这个域名,一般来说,浏览器会首先查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,如果有的话就直接使用 hosts 文件里面的 ip 地址。

          2、如果在本地的 hosts 文件没有能够找到对应的 ip 地址,浏览器会发出一个 DNS请求到本地DNS服务器 。本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。

        3、查询你输入的网址的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,本地DNS服务器还要向DNS根服务器进行查询。

      4、根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。这种过程是迭代的过程。

      5、本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。

      6、最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。

     

    下面这张图很完美的解释了这一过程:

    知识扩展:

    1)什么是DNS?

      DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。

      通俗的讲,我们更习惯于记住一个网站的名字,比如www.baidu.com,而不是记住它的ip地址,比如:167.23.10.2。而计算机更擅长记住网站的ip地址,而不是像www.baidu.com等链接。因为,DNS就相当于一个电话本,比如你要找www.baidu.com这个域名,那我翻一翻我的电话本,我就知道,哦,它的电话(ip)是167.23.10.2。

     

    2)DNS查询的两种方式:递归查询和迭代查询

    1、递归解析

        当局部DNS服务器自己不能回答客户机的DNS查询时,它就需要向其他DNS服务器进行查询。此时有两种方式,如图所示的是递归方式。局部DNS服务器自己负责向其他DNS服务器进行查询,一般是先向该域名的根域服务器查询,再由根域名服务器一级级向下查询。最后得到的查询结果返回给局部DNS服务器,再由局部DNS服务器返回给客户端。

    2、迭代解析

      当局部DNS服务器自己不能回答客户机的DNS查询时,也可以通过迭代查询的方式进行解析,如图所示。局部DNS服务器不是自己向其他DNS服务器进行查询,而是把能解析该域名的其他DNS服务器的IP地址返回给客户端DNS程序,客户端DNS程序再继续向这些DNS服务器进行查询,直到得到查询结果为止。也就是说,迭代解析只是帮你找到相关的服务器而已,而不会帮你去查。比如说:baidu.com的服务器ip地址在192.168.4.5这里,你自己去查吧,本人比较忙,只能帮你到这里了。

     

    3)DNS域名称空间的组织方式

     我们在前面有说到根DNS服务器,域DNS服务器,这些都是DNS域名称空间的组织方式。按其功能命名空间中用来描述 DNS 域名称的五个类别的介绍详见下表中,以及与每个名称类型的示例

    (盗图)

     

    4)DNS负载均衡

      当一个网站有足够多的用户的时候,假如每次请求的资源都位于同一台机器上面,那么这台机器随时可能会蹦掉。处理办法就是用DNS负载均衡技术,它的原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等。

    3、浏览器向 web 服务器发送一个 HTTP 请求

      拿到域名对应的IP地址之后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有httpd,nginx等)80端口发起TCP的连接请求这个连接请求到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。

    TCP连接如图所示:

      建立了TCP连接之后,发起一个http请求。一个典型的 http request header 一般需要包括请求的方法,例如 GET 或者 POST 等,不常用的还有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的浏览器只能发起 GET 或者 POST 请求。

      客户端向服务器发起http请求的时候,会有一些请求信息,请求信息包含三个部分:

      | 请求方法URI协议/版本

          | 请求头(Request Header)

      | 请求正文:

    下面是一个完整的HTTP请求例子:

    复制代码
    GET/sample.jspHTTP/1.1
    Accept:image/gif.image/jpeg,*/*
    Accept-Language:zh-cn
    Connection:Keep-Alive
    Host:localhost
    User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
    Accept-Encoding:gzip,deflate
    username=jinqiao&password=1234
    复制代码

     注意:最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

    (1)请求的第一行是“方法URL议/版本”:GET/sample.jsp HTTP/1.1
    (2)请求头(Request Header)
       请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。

    Accept:image/gif.image/jpeg.*/*
    Accept-Language:zh-cn
    Connection:Keep-Alive
    Host:localhost
    User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
    Accept-Encoding:gzip,deflate.

    (3)请求正文
        请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息:

    username=jinqiao&password=1234

     

    知识扩展:

    1)TCP三次握手

    第一次握手:客户端A将标志位SYN置为1,随机产生一个值为seq=J(J的取值范围为=1234567)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认;

    第二次握手:服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_RCVD状态。

    第三次握手:客户端A收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务端B,服务端B检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态,完成三次握手,随后客户端A与服务端B之间可以开始传输数据了。

    如图所示:

     

     

    2)为什需要三次握手?

      《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”

       书中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。

      假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。主要目的防止server端一直等待,浪费资源。

     

    3)TCP四次挥手

    第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
    第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
    第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
    第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

     

    4)为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

      这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。

    4、服务器的永久重定向响应

       服务器给浏览器响应一个301永久重定向响应,这样浏览器就会访问“http://www.google.com/” 而非“http://google.com/”。

      为什么服务器一定要重定向而不是直接发送用户想看的网页内容呢?其中一个原因跟搜索引擎排名有关。如果一个页面有两个地址,就像http://www.yy.com/和http://yy.com/,搜索引擎会认为它们是两个网站,结果造成每个搜索链接都减少从而降低排名。而搜索引擎知道301永久重定向是什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。还有就是用不同的地址会造成缓存友好性变差,当一个页面有好几个名字时,它可能会在缓存里出现好几次。

    扩展知识

    1)301和302的区别。

      301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。

      他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址

      302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于301

     

    2)重定向原因:

    (1)网站调整(如改变网页目录结构);
    (2)网页被移到一个新地址;
    (3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。
            这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。
     

    3)什么时候进行301或者302跳转呢?

            当一个网站或者网页24—48小时内临时移动到一个新的位置,这时候就要进行302跳转,而使用301跳转的场景就是之前的网站因为某种原因需要移除掉,然后要到新的地址访问,是永久性的。
    清晰明确而言:使用301跳转的大概场景如下:
    1、域名到期不想续费(或者发现了更适合网站的域名),想换个域名。
    2、在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。
    3、空间服务器不稳定,换空间的时候。

    5、浏览器跟踪重定向地址

       现在浏览器知道了 "http://www.google.com/"才是要访问的正确地址,所以它会发送另一个http请求。这里没有啥好说的

     

    6、服务器处理请求

      经过前面的重重步骤,我们终于将我们的http请求发送到了服务器这里,其实前面的重定向已经是到达服务器了,那么,服务器是如何处理我们的请求的呢?

      后端从在固定的端口接收到TCP报文开始,它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。

      一些大一点的网站会将你的请求到反向代理服务器中,因为当网站访问量非常大,网站越来越慢,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。此时,客户端不是直接通过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,然后将结果返回给客户端,这里Nginx的作用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。

    如图所示:

    通过Nginx的反向代理,我们到达了web服务器,服务端脚本处理我们的请求,访问我们的数据库,获取需要获取的内容等等,当然,这个过程涉及很多后端脚本的复杂操作。由于对这一块不熟,所以这一块只能介绍这么多了。

     

    扩展阅读:

    1)什么是反向代理?

    客户端本来可以直接通过HTTP协议访问某网站应用服务器,网站管理员可以在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端,此时Nginx就是反向代理服务器。

     

    7、服务器返回一个 HTTP 响应 

      经过前面的6个步骤,服务器收到了我们的请求,也处理我们的请求,到这一步,它会把它的处理结果返回,也就是返回一个HTPP响应。

    HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成,分别是:

    l  状态行

    l  响应头(Response Header)

    l  响应正文

    复制代码
    HTTP/1.1 200 OK
    Date: Sat, 31 Dec 2005 23:59:59 GMT
    Content-Type: text/html;charset=ISO-8859-1
    Content-Length: 122
    
    <html>
    <head>
    <title>http</title>
    </head>
    <body>
    <!-- body goes here -->
    </body>
    </html>
    复制代码

    状态行:

    状态行由协议版本、数字形式的状态代码、及相应的状态描述,各元素之间以空格分隔。

    格式:    HTTP-Version Status-Code Reason-Phrase CRLF

    例如:    HTTP/1.1 200 OK \r\n

    -- 协议版本:是用http1.0还是其他版本

    -- 状态描述:状态描述给出了关于状态代码的简短的文字描述。比如状态代码为200时的描述为 ok

    -- 状态代码:状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。如下

     

    1xx:信息性状态码,表示服务器已接收了客户端请求,客户端可继续发送请求。

        100 Continue

        101 Switching Protocols

     2xx:成功状态码,表示服务器已成功接收到请求并进行处理。

        200 OK 表示客户端请求成功

        204 No Content 成功,但不返回任何实体的主体部分

        206 Partial Content 成功执行了一个范围(Range)请求

    3xx:重定向状态码,表示服务器要求客户端重定向。

        301 Moved Permanently 永久性重定向,响应报文的Location首部应该有该资源的新URL

        302 Found 临时性重定向,响应报文的Location首部给出的URL用来临时定位资源

        303 See Other 请求的资源存在着另一个URI,客户端应使用GET方法定向获取请求的资源

        304 Not Modified 服务器内容没有更新,可以直接读取浏览器缓存

         307 Temporary Redirect 临时重定向。与302 Found含义一样。302禁止POST变换为GET,但实际使用时并不一定,307则更多浏览器可能会遵循这一标准,但也依赖于浏览器具体实现

     4xx:客户端错误状态码,表示客户端的请求有非法内容。

           400 Bad Request 表示客户端请求有语法错误,不能被服务器所理解

           401 Unauthonzed 表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用

           403 Forbidden 表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因

           404 Not Found 请求的资源不存在,例如,输入了错误的URL

    5xx:服务器错误状态码,表示服务器未能正常处理客户端的请求而出现意外错误。

            500 Internel Server Error 表示服务器发生不可预期的错误,导致无法完成客户端的请求

            503 Service Unavailable 表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常

     

    响应头:

      响应头部:由关键字/值对组成,每行一对,关键字和值用英文冒号":"分隔,典型的响应头有:

     

    响应正文

    包含着我们需要的一些具体信息,比如cookie,html,image,后端返回的请求数据等等。这里需要注意,响应正文和响应头之间有一行空格,表示响应头的信息到空格为止,下图是fiddler抓到的请求正文,红色框中的:响应正文:

     

    8、浏览器显示 HTML

      在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了,浏览器是如何把页面呈现在屏幕上的呢?不同浏览器可能解析的过程不太一样,这里我们只介绍webkit的渲染过程,下图对应的就是WebKit渲染的过程,这个过程包括:

    解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树



      浏览器在解析html文件时,会”自上而下“加载,并在加载过程中进行解析渲染。在解析过程中,如果遇到请求外部资源时,如图片、外链的CSS、iconfont等,请求过程是异步的,并不会影响html文档进行加载。

      解析过程中,浏览器首先会解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)。

      DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。

      页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。

      

      当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。因为JS有可能会修改DOM,最为经典的document.write,这意味着,在JS执行完成前,后续所有资源的下载可能是没有必要的,这是js阻塞后续资源下载的根本原因。所以我明平时的代码中,js是放在html文档末尾的。

      JS的解析是由浏览器中的JS解析引擎完成的,比如谷歌的是V8。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。

      JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。具体的过程可以看我这篇文章:点击这里

     

    9、浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)

      其实这个步骤可以并列在步骤8中,在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。比如我要获取外图片,CSS,JS文件等,类似于下面的链接:

    图片:http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif

    CSS式样表:http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css

    JavaScript 文件:http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js

      这些地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等...

    不像动态页面,静态文件会允许浏览器对其进行缓存。有的文件可能会不需要与服务器通讯,而从缓存中直接读取,或者可以放到CDN中

    展开全文
  • 输入URL到页面展示的这个过程中牵扯太多知识点,这里做一个大概的整理。文章主要内容摘自以下参考文献,流程有调整,为个人整理。 参考文章主要有: https://www.cnblogs.com/xiaohuochai/p/9193083.html ...

    从输入URL到页面展示的这个过程中牵扯到太多知识点,这里做一个大概的整理。文章主要内容摘自以下参考文献,流程有调整,为个人整理。
    参考文章主要有:
    https://www.cnblogs.com/xiaohuochai/p/9193083.html
    https://blog.csdn.net/wlk2064819994/article/details/79756669(转载自https://www.cnblogs.com/xianyulaodi/p/6547807.html的一篇博文)
    https://segmentfault.com/a/1190000006879700
    TCP的三次握手和四次挥手:
    https://blog.csdn.net/qq_38950316/article/details/81087809
    https://www.jianshu.com/p/29868fb82890
    TCP的拥塞控制参考:https://www.cnblogs.com/losbyday/p/5847041.html

    大概流程:

    1. 输入url地址
    2. 应用层进行DNS解析
    3. 应用层生成HTTP请求报文
    4. 传输层建立TCP连接
    5. 网络层使用IP协议来选择路线
    6. 数据链路层实现网络相邻节点间可靠的数据通信
    7. 物理层传输数据
    8. 服务器处理反向传输
    9. 服务器返回一个 HTTP 响应
    10. 浏览器渲染

    写在前边:

    从输入URL到页面加载的主干流程如下:(参考https://www.cnblogs.com/xiaohuochai/p/9193083.html)
      1、浏览器构建HTTP Request请求
      2、网络传输
      3、服务器构建HTTP Response 响应
      4、网络传输
      5、浏览器渲染页面
    在这里插入图片描述
    (图源自:https://www.cnblogs.com/xiaohuochai/p/9193083.html)

    1. 输入url地址

    当我们开始在浏览器中输入网址的时候,浏览器其实就已经在智能的匹配可能得 url 了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url,然后给出智能提示,让你可以补全url地址。对于 google的chrome 的浏览器,他甚至会直接从缓存中把网页展示出来,就是说,你还没有按下 enter,页面就出来了。

    2. 应用层进行DNS解析

    (1)什么是DNS?

    DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。
      通俗的讲,我们更习惯于记住一个网站的名字,比如www.baidu.com,而不是记住它的ip地址,比如:167.23.10.2。而计算机更擅长记住网站的ip地址,而不是像www.baidu.com等链接。因为,DNS就相当于一个电话本,比如你要找www.baidu.com这个域名,那我翻一翻我的电话本,我就知道,哦,它的电话(ip)是167.23.10.2。

    (2)DNS查询的两种方式:递归查询和迭代查询

    1、递归解析

    当局部DNS服务器自己不能回答客户机的DNS查询时,它就需要向其他DNS服务器进行查询。此时有两种方式,如图所示的是递归方式。局部DNS服务器自己负责向其他DNS服务器进行查询,一般是先向该域名的根域服务器查询,再由根域名服务器一级级向下查询。最后得到的查询结果返回给局部DNS服务器,再由局部DNS服务器返回给客户端。

    2、迭代解析

    当局部DNS服务器自己不能回答客户机的DNS查询时,也可以通过迭代查询的方式进行解析,如图所示。局部DNS服务器不是自己向其他DNS服务器进行查询,而是把能解析该域名的其他DNS服务器的IP地址返回给客户端DNS程序,客户端DNS程序再继续向这些DNS服务器进行查询,直到得到查询结果为止。也就是说,迭代解析只是帮你找到相关的服务器而已,而不会帮你去查。比如说:baidu.com的服务器ip地址在192.168.4.5这里,你自己去查吧,本人比较忙,只能帮你到这里了。

    在这里插入图片描述
    (图源自https://segmentfault.com/a/1190000006879700)

    (3)DNS域名称空间的组织方式

    我们在前面有说到根DNS服务器,域DNS服务器,这些都是DNS域名称空间的组织方式。按其功能命名空间中用来描述 DNS 域名称的五个类别的介绍详见下表中,以及与每个名称类型的示例
    ()
    (盗图)(图源于:https://blog.csdn.net/wlk2064819994/article/details/79756669)

    (4)DNS优化

    了解了DNS的过程,可以为我们带来哪些?上文中请求到google的IP地址时,经历了8个步骤,这个过程中存在多个请求(同时存在UDP和TCP请求,为什么有两种请求方式,请自行查找)。如果每次都经过这么多步骤,是否太耗时间?如何减少该过程的步骤呢?那就是DNS缓存。

    DNS缓存
    DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS(运营商)服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。

    (5)DNS负载均衡

    • 不知道大家有没有思考过一个问题: DNS返回的IP地址是否每次都一样?
    • 如果每次都一样是否说明你请求的资源都位于同一台机器上面,那么这台机器需要多高的性能和储存才能满足亿万请求呢?其实真实的互联网世界背后存在成千上百台服务器,大型的网站甚至更多。
    • 但是在用户的眼中,它需要的只是处理他的请求,哪台机器处理请求并不重要。DNS可以返回一个合适的机器的IP给用户。
    • 可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡,又叫做DNS重定向。
    • 大家耳熟能详的CDN(Content Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。在这里打个免费的广告,我平时使用的比较多的是七牛云的CDN(免费)储存图片。

    原理:在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。

    3. 应用层生成HTTP请求报文

    应用层生成针对目标WEB服务器的HTTP请求报文,HTTP请求报文包括起始行、首部(请求头(Request Header))和主体(请求正文)部分。

    GET/sample.jspHTTP/1.1
    Accept:image/gif.image/jpeg,*/*
    Accept-Language:zh-cn
    Connection:Keep-Alive
    Host:localhost
    User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
    Accept-Encoding:gzip,deflate
    
    username=jinqiao&password=1234
    
    • 起始行:请求方法URI协议/版本(GET/sample.jsp HTTP/1.1)
    • 首部:包括域名host、keep-alive、User-Agent、Accept-Encoding、Accept-Language、Cookie等信息。请求头(Request Header)请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。
    • 请求正文:主体内容即要传输的内容。如果是get请求,则主体内容为空
    • 请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息:
    username=jinqiao&password=1234
    

    重要插入:HTTPS协议:

    TTP报文是包裹在TCP报文中发送的,服务器端收到TCP报文时会解包提取出HTTP报文。但是这个过程中存在一定的风险,HTTP报文是明文,如果中间被截取的话会存在一些信息泄露的风险。那么在进入TCP报文之前对HTTP做一次加密就可以解决这个问题了。HTTPS协议的本质就是HTTP + SSL(or TLS)。在HTTP报文进入TCP报文之前,先使用SSL对HTTP报文进行加密。从网络的层级结构看它位于HTTP协议与TCP协议之间。
    在这里插入图片描述
    (图源自https://segmentfault.com/a/1190000006879700)
    HTTPS过程

    • HTTPS在传输数据之前需要客户端与服务器进行一个握手(TLS/SSL握手);
    • 在握手过程中将确立双方加密传输数据的密码信息;
    • TLS/SSL使用了非对称加密,对称加密以及hash等;(具体过程请参考经典的阮一峰先生的博客TLS/SSL握手过程。)
    • HTTPS相比于HTTP,虽然提供了安全保证,但是势必会带来一些时间上的损耗,如握手和加密等过程,是否使用HTTPS需要根据具体情况在安全和性能方面做出权衡。

    4. 传输层建立TCP连接

    • 传输层传输协议分为UDP和TCP两种

    UDP是无连接的协议,而TCP是可靠的有连接的协议,主要表现在:接收方会对收到的数据进行确认、发送方会重传接收方未确认的数据、接收方会将接收到数据按正确的顺序重新排序,并删除重复的数据、提供了控制拥挤的机制(TCP的拥塞控制参考:https://www.cnblogs.com/losbyday/p/5847041.html)

    由于HTTP协议使用的是TCP协议,为了方便通信,将HTTP请求报文按序号分为多个报文段(segment),并对每个报文段进行封装。使用本地一个大于1024以上的随机TCP源端口(这里假设是1030)建立到目的服务器TCP80号端口(HTTPS协议对应的端口号是443)的连接,TCP源端口和目的端口被加入到报文段中,学名叫协议数据单元(Protocol Data Unit, PDU)。因TCP是一个可靠的传输控制协议,传输层还会加入序列号、确认号、窗口大小、校验和等参数,共添加20字节的头部信息。
    在这里插入图片描述
    (图源自:https://www.cnblogs.com/xiaohuochai/p/9193083.html)

    • 浏览器向 web 服务器发送一个 HTTP 请求:
      在这里插入图片描述
    • 三次握手(建立连接):
      在这里插入图片描述
      在这里插入图片描述
    • 构建TCP请求会增加大量的网络时延,常用的优化方式如下所示

    (1)资源打包,合并请求

    (2)多使用缓存,减少网络传输

    (3)使用keep-alive建立持久连接

    (4)使用多个域名,增加浏览器的资源并发加载数,或者使用HTTP2的管道化连接的多路复用技术

    • 四次挥手(断开连接):

    在这里插入图片描述
    在这里插入图片描述
    (图源自:https://www.jianshu.com/p/29868fb82890)
    TCP三次握手和四次挥手详解:
    https://www.jianshu.com/p/29868fb82890

    5. 网络层使用IP协议来选择路线

    处理来自传输层的数据段segment,将数据段segment装入数据包packet,填充包头,主要就是添加源和目的IP地址,然后发送数据。在数据传输的过程中,IP协议负责选择传送的路线,称为路由功能

    6. 数据链路层实现网络相邻节点间可靠的数据通信

    为了保证数据的可靠传输,把数据包packet封装成帧(Frame),并按顺序传送各帧。由于物理线路的不可靠,发出的数据帧有可能在线路上出错或丢失,于是为每个数据分块计算出CRC(循环冗余检验),并把CRC添加到帧中,这样接收方就可以通过重新计算CRC来判断数据接收的正确性。一旦出错就重传

    将数据包packet封装成帧(Frame),包括帧头和帧尾。帧尾是添加被称做CRC的循环冗余校验部分。帧头主要是添加数据链路层的地址,即数据链路层的源地址和目的地址,即网络相邻结点间的源MAC地址和目的MAC地址

    7. 物理层传输数据

    数据链路层的帧(Frame)转换成二进制形式的比特(Bit)流,从网卡发送出去,再把比特转换成电子、光学或微波信号在网络中传输

    补充:网络传输

    从客户机到服务器需要通过许多网络设备, 一般地,包括集线器、交换器、路由器等

    【集线器】

    集线器是物理层设备,比特流到达集线器后,集线器简单地对比特流进行放大,从除接收端口以外的所有端口转发出去

    【交换机】

    交换机是数据链路层设备,比特流到达交换机,交换机除了对比特流进行放大外,还根据源MAC地址进行学习,根据目的MAC地址进行转发。交换机根据数据帧中的目的MAC地址査询MAC地址表,把比特流从对应的端口发送出去

    【路由器】
      路由器是网络层设备,路由器收到比特流,转换成帧上传到数据链路层,路由器比较数据帧的目的MAC地址,如果有与路由器接收端口相同的MAC地址,则路由器的数据链路层把数据帧进行解封装,然后上传到路由器的网络层,路由器找到数据包的目的IP地址,并查询路由表,将数据从入端口转发到出端口。接着在网络层重新封装成数据包packet,下沉到数据链路层重新封装成帧frame,下沉到物理层,转换成二进制比特流,发送出去

    8. 服务器处理反向传输

    服务器接收到这个比特流,把比特流转换成帧格式,上传到数据链路层,服务器发现数据帧中的目的MAC地址与本网卡的MAC地址相同,服务器拆除数据链路层的封装后,把数据包上传到网络层。服务器的网络层比较数据包中的目的IP地址,发现与本机的IP地址相同,服务器拆除网络层的封装后,把数据分段上传到传输层。传输层对数据分段进行确认、排序、重组,确保数据传输的可靠性。数据最后被传到服务器的应用层

    HTTP服务器,如nginx通过反向代理,将其定位到服务器实际的端口位置,如8080。比如,8080端口对应的是一个NodeJS服务,生成响应报文,报文主体内容是google首页的HTML页面

    接着,通过传输层、网络层、数据链路层的层层封装,最终将响应报文封装成二进制比特流,并转换成其他信号,如电信号到网络中传输

    反向传输的过程与正向传输的过程类似,就不再赘述

    9. 服务器返回一个 HTTP 响应

    自然而然这部分对应的就是后端工程师眼中的HTTP。后端从在固定的端口接收到TCP报文开始,这一部分对应于编程语言中的socket。它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,我使用过的Web服务器有Tomcat, Jetty和Netty等等。

    HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文。

    HTTP/1.1 200 OK
    Date: Sat, 31 Dec 2005 23:59:59 GMT
    Content-Type: text/html;charset=ISO-8859-1
    Content-Length: 122
    
    <html>
    <head>
    <title>http</title>
    </head>
    <body>
    <!-- body goes here -->
    </body>
    </html>
    

    状态行:

    状态行由协议版本、数字形式的状态代码、及相应的状态描述,各元素之间以空格分隔。

    • 格式: HTTP-Version Status-Code Reason-Phrase CRLF
    • 例如: HTTP/1.1 200 OK \r\n

    – 协议版本:是用http1.0还是其他版本

    – 状态描述:状态描述给出了关于状态代码的简短的文字描述。比如状态代码为200时的描述为 ok

    – 状态代码:状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。

    响应报头
    常见的响应报头字段有: Server, Connection…。

    响应报文
    服务器返回给浏览器的文本信息,通常HTML, CSS, JS, 图片等文件就放在这一部分。

    如果HTTP响应报文是301或302重定向,则浏览器会依相应头中的location再次发送请求。

    1)301和302的区别。

    301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。

    他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;

    302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于301

    2)重定向原因:

    (1)网站调整(如改变网页目录结构);
    (2)网页被移到一个新地址;
    (3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。
    这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。

    3)什么时候进行301或者302跳转呢?

        当一个网站或者网页24—48小时内临时移动到一个新的位置,这时候就要进行302跳转,而使用301跳转的场景就是之前的网站因为某种原因需要移除掉,然后要到新的地址访问,是永久性的。
    

    清晰明确而言:使用301跳转的大概场景如下:
    1、域名到期不想续费(或者发现了更适合网站的域名),想换个域名。
    2、在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。
    3、空间服务器不稳定,换空间的时候。

    4)状态码

    状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:

    1xx:指示信息–表示请求已接收,继续处理。

    2xx:成功–表示请求已被成功接收、理解、接受。

    3xx:重定向–要完成请求必须进行更进一步的操作。

    4xx:客户端错误–请求有语法错误或请求无法实现。

    5xx:服务器端错误–服务器未能实现合法的请求。
    平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500。

    • 200 OK 表示客户端请求成功
    • 204 No Content 成功,但不返回任何实体的主体部分
    • 206 Partial Content 成功执行了一个范围(Range)请求
    • 301 Moved Permanently 永久性重定向,响应报文的Location首部应该有该资源的新URL
    • 302 Found 临时性重定向,响应报文的Location首部给出的URL用来临时定位资源
    • 303 See Other 请求的资源存在着另一个URI,客户端应使用GET方法定向获取请求的资源
    • 304 Not Modified 服务器内容没有更新,可以直接读取浏览器缓存
    • 400 Bad Request 表示客户端请求有语法错误,不能被服务器所理解
    • 401 Unauthonzed 表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用
    • 403 Forbidden 表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因
    • 404 Not Found 请求的资源不存在,例如,输入了错误的URL
    • 500 Internel Server Error 表示服务器发生不可预期的错误,导致无法完成客户端的请求
    • 503 Service Unavailable 表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常

    10. 浏览器渲染

    客户机接受到二进制比特流之后,把比特流转换成帧格式,上传到数据链路层,客户机发现数据帧中的目的MAC地址与本网卡的MAC地址相同,拆除数据链路层的封装后,把数据包上传到网络层。网络层比较数据包中的目的IP地址,发现与本机的IP地址相同,拆除网络层的封装后,把数据分段上传到传输层。传输层对数据分段进行确认、排序、重组,确保数据传输的可靠性。数据最后被传到应用层。

    浏览器在收到HTML,CSS,JS文件后,它是如何把页面呈现到屏幕上的?

    主资源到达后,浏览器的Parser模块解析主资源的内容,生成派生资源对应的DOM结构,然后根据需求触发派生资源的加载流程。比如,在解析过程中,如果遇到img的起始标签,会创建相应的image元素HTMLImageElement,接着依据img标签的内容设置HTMLImageElement的属性。在设置src属性时,会触发图片资源加载,发起加载资源请求

    这里常见的优化点是对派生资源使用缓存

    1)、使用parse模块解析HTML、CSS、Javascript资源

    【解析HTML】

    HTML解析分为可以分为解码、分词、解析、建树四个步骤

    (1)解码:将网络上接收到的经过编码的字节流,解码成Unicode字符

    (2)分词:按照一定的切词规则,将Unicode字符流切成一个个的词语(Tokens)

    (3)解析:根据词语的语义,创建相应的节点(Node)

    (4)建树:将节点关联到一起,创建DOM树

    【解析CSS】

    页面中所有的CSS由样式表CSSStyleSheet集合构成,而CSSStyleSheet是一系列CSSRule的集合,每一条CSSRule则由选择器CSSStyleSelector部分和声明CSSStyleDeclaration部分构成,而CSSStyleDeclaration是CSS属性和值的Key-Value集合

    CSS解析完毕后会进行CSSRule的匹配过程,即寻找满足每条CSS规则Selector部分的HTML元素,然后将其Declaration声明部分应用于该元素。实际的规则匹配过程会考虑到默认和继承的CSS属性、匹配的效率及规则的优先级等因素

    【解析JS】

    JavaScript一般由单独的脚本引擎解析执行,它的作用通常是动态地改变DOM树(比如为DOM节点添加事件响应处理函数),即根据时间(timer)或事件(event)映射一棵DOM树到另一棵DOM树

    简单来说,经过了Parser模块的处理,浏览器把页面文本转换成了一棵节点带CSS Style、会响应自定义事件的Styled DOM树

    2)、构建DOM树、Render树及RenderLayer树

    浏览器的解析过程就是将字节流形式的网页内容构建成DOM树、Render树及RenderLayer树的过程

    使用parse解析HTML的过程,已经完成了DOM树的构建,接下来构建Render树

    【Render树】

    Render树用于表示文档的可视信息,记录了文档中每个可视元素的布局及渲染方式

    RenderObject是Render树所有节点的基类,作用类似于DOM树的Node类。这个类存储了绘制页面可视元素所需要的样式及布局信息,RenderObject对象及其子类都知道如何绘制自己。事实上绘制Render树的过程就是RenderObject按照一定顺序绘制自身的过程

    DOM树上的节点与Render树上的节点并不是一一对应的。只有DOM树的根节点及可视节点才会创建对应的RenderObject节点

    【Render Layer树】

    Render Layer树以层为节点组织文档的可视信息,网页上的每一层对应一个Render Layer对象。RenderLayer树可以看作Render树的稀疏表示,每个RenderLayer树的节点都对应着一棵Render树的子树,这棵子树上所有Render节点都在网页的同一层显示

    RenderLayer树是基于RenderObject树构建的,满足一定条件的RenderObject才会建立对应的RenderLayer节点

    下面是RenderLayer节点的创建条件:

    (1)网页的root节点

    (2)有显式的CSS position属性(relative,absolute,fixed)

    (3)元素设置了transform

    (4)元素是透明的,即opacity不等于1

    (5)节点有溢出(overflow)、alpha mask或者反射(reflection)效果。

    (6)元素有CSS filter(滤镜)属性

    (7)2D Canvas或者WebGL

    (8)Video元素

    3)、布局和渲染

    布局就是安排和计算页面中每个元素大小位置等几何信息的过程。HTML采用流式布局模型,基本的原则是页面元素在顺序遍历过程中依次按从左至右、从上至下的排列方式确定各自的位置区域

    简单情况下,布局可以顺序遍历一次Render树完成,但也有需要迭代的情况。当祖先元素的大小位置依赖于后代元素或者互相依赖时,一次遍历就无法完成布局,如Table元素的宽高未明确指定而其下某一子元素Tr指定其高度为父Table高度的30%的情况

    Paint模块负责将Render树映射成可视的图形,它会遍历Render树调用每个Render节点的绘制方法将其内容显示在一块画布或者位图上,并最终呈现在浏览器应用窗口中成为用户看到的实际页面

    主要绘制顺序如下:

    (1)背景颜色

    (2)背景图片

    (3)边框

    (4)子呈现树节点

    (5)轮廓

    4)、硬件加速

    开启硬件渲染,即合成加速,会为需要单独绘制的每一层创建一个GraphicsLayer

    硬件渲染是指网页各层的合成是通过GPU完成的,它采用分块渲染的策略,分块渲染是指:网页内容被一组Tile覆盖,每块Tile对应一个独立的后端存储,当网页内容更新时,只更新内容有变化的Tile。分块策略可以做到局部更新,渲染效率更高

    一个Render Layer对象如果需要后端存储,它会创建一个Render Layer Backing对象,该对象负责Renderlayer对象所需要的各种存储。如果一个Render Layer对象可以创建后端存储,那么将该RenderLayer称为合成层(Compositing Layer)

    如果一个Render Layer对象具有以下的特征之一,那么它就是合成层:

    (1)RenderLayer具有CSS 3D属性或者CSS透视效果。

    (2)RenderLayer包含的RenderObject节点表示的是使用硬件加速的视频解码技术的HTML5 ”video”元素。

    (3) RenderLayer包含的RenderObject节点表示的是使用硬件加速的Canvas2D元素或者WebGL技术。

    (4)RenderLayer使用了CSS透明效果的动画或者CSS变换的动画。

    (5)RenderLayer使用了硬件加速的CSSfilters技术。

    (6)RenderLayer使用了剪裁(clip)或者反射(reflection)属性,并且它的后代中包括了一个合成层。

    (7)RenderLayer有一个Z坐标比自己小的兄弟节点,该节点是一个合成层

    最终的渲染流程如下所示:
      在这里插入图片描述
    (图源自:https://www.cnblogs.com/xiaohuochai/p/9193083.html)
    【重绘和回流】

    重绘和回流是在页面渲染过程中非常重要的两个概念。页面生成以后,脚本操作、样式表变更,以及用户操作都可能触发重绘和回流

    回流reflow是firefox里的术语,在chrome中称为重排relayout

    回流是指窗口尺寸被修改、发生滚动操作,或者元素位置相关属性被更新时会触发布局过程,在布局过程中要计算所有元素的位置信息。由于HTML使用的是流式布局,如果页面中的一个元素的尺寸发生了变化,则其后续的元素位置都要跟着发生变化,也就是重新进行流式布局的过程,所以被称之为回流

    前面介绍过渲染引擎生成的3个树:DOM树、Render树、Render Layer树。回流发生在Render树上。常说的脱离文档流,就是指脱离渲染树Render Tree

    重绘是指当与视觉相关的样式属性值被更新时会触发绘制过程,在绘制过程中要重新计算元素的视觉信息,使元素呈现新的外观

    由于元素的重绘repaint只发生在渲染层 render layer上。所以,如果要改变元素的视觉属性,最好让该元素成为一个独立的渲染层render layer

    下面列举一些减少回流次数的方法

    (1)不要一条一条地修改DOM样式,而是修改className或者修改style.cssText

    (2)在内存中多次操作节点,完成后再添加到文档中去

    (3)对于一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示

    (4)在需要经常获取那些引起浏览器回流的属性值时,要缓存到变量中

    (5)不要使用table布局,因为一个小改动可能会造成整个table重新布局。而且table渲染通常要3倍于同等元素时间

    此外,将需要多次重绘的元素独立为render layer渲染层,如设置absolute,可以减少重绘范围;对于一些进行动画的元素,可以进行硬件渲染,从而避免重绘和回流
     
    本文内容主要摘自其他参考文章,流程有调整,为个人整理,不到之处,欢迎留言指正。

    展开全文
  • 文章目录基本背景知识介绍最新的 Chrome 进程架构完整的 TCP 连接过程完整的HTTP 请求流程完整的渲染流水线从输入 URL 到页面展示完整流程结语 注:本篇博客的内容来源自极客时间李兵老师的“浏览器工作原理与实践”...


    注:本篇博客的内容来源自极客时间李兵老师的“浏览器工作原理与实践”课程的笔记总结

    基本背景知识介绍

    最新的 Chrome 进程架构

    下图是最新的Chrome进程架构图:
    在这里插入图片描述
    从图中可以看出,最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。
    下面具体介绍这几个进程的功能:

    1. 浏览器进程: 主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
    2. 渲染进程: 核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
    3. GPU 进程: 其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
    4. 网络进程: 主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
    5. 插件进程: 主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

    完整的 TCP 连接过程

    下图为完整的 TCP 连接过程图:
    在这里插入图片描述
    从图中不难看出,一个完整的 TCP 连接的生命周期包括了“建立连接”“传输数据”和“断开连接”三个阶段。

    完整的HTTP 请求流程

    下图为完整的HTTP 请求流程图:
    在这里插入图片描述
    从图中可以看到,浏览器中的 HTTP 请求从发起到结束一共经历了如下八个阶段:构建请求、查找缓存、准备 IP 和端口、等待 TCP 队列、建立 TCP 连接、发起 HTTP 请求、服务器处理请求、服务器返回请求和断开连接。

    完整的渲染流水线

    下图为完整的渲染流程图:
    在这里插入图片描述
    此完整的渲染流程大致可总结为如下:

    1. 渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。
    2. 渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。
    3. 创建布局树,并计算元素的布局信息。
    4. 对布局树进行分层,并生成分层树。
    5. 为每个图层生成绘制列表,并将其提交到合成线程。
    6. 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
    7. 合成线程发送绘制图块命令 DrawQuad 给浏览器进程。
    8. 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

    从输入 URL 到页面展示完整流程

    介绍完前面所需要的三个基本知识背景后(HTTP 请求流程包括了TCP连接),现在只需要将其串起来就能回答从输入 URL 到页面展示完整流程。
    同样,先给出从输入 URL 到页面展示完整流程示意图:
    在这里插入图片描述
    由图中不难发现,最外层是三种Chrome进程,而网络进程所执行的操作就是HTTP 请求流程并且渲染进程所执行的操作就是渲染流程。
    下面,先给出此流程图精简版的描述:

    • 首先,浏览器进程接收到用户输入的 URL 请求,浏览器进程便将该 URL 转发给网络进程。
    • 然后,在网络进程中发起真正的 URL 请求。
    • 接着网络进程接收到了响应头数据,便解析响应头数据,并将数据转发给浏览器进程。
    • 浏览器进程接收到网络进程的响应头数据之后,发送“提交导航 (CommitNavigation)”消息到渲染进程。
    • 渲染进程接收到“提交导航”的消息之后,便开始准备接收 HTML 数据,接收数据的方式是直接和网络进程建立数据管道。
    • 最后渲染进程会向浏览器进程“确认提交”,这是告诉浏览器进程:“已经准备好接受和解析页面数据了”。
    • 浏览器进程接收到渲染进程“提交文档”的消息之后,便开始移除之前旧的文档,然后更新浏览器进程中的页面状态。

    下面还有一个结合前面基础知识的更详细的流程描述:
    用户输入

    1. 用户在地址栏按下回车,检查输入(关键字 or 符合 URL 规则),组装完整 URL;
    2. 回车前,当前页面执行 onbeforeunload 事件;
    3. 浏览器进入加载状态。

    URL 请求

    1. 浏览器进程通过 IPC 把 URL 请求发送至网络进程;
    2. 查找资源缓存(有效期内);
    3. DNS 解析(查询 DNS 缓存);
    4. 进入 TCP 队列(单个域名 TCP 连接数量限制);
    5. 创建 TCP 连接(三次握手);
    6. HTTPS 建立 TLS 连接(client hello, server hello, pre-master key 生成『对话密钥』);
    7. 发送 HTTP 请求(请求行[方法、URL、协议]、请求头 Cookie 等、请求体 POST);
    8. 接受请求(响应行[协议、状态码、状态消息]、响应头、响应体等);
      • 状态码 301 / 302,根据响应头中的 Location 重定向;
      • 状态码 200,根据响应头中的 Content-Type 决定如何响应(下载文件、加载资源、渲染 HTML)。

    准备渲染进程

    1. 根据是否同一站点(相同的协议和根域名),决定是否复用渲染进程。

    提交文档

    1. 浏览器进程接受到网路进程的响应头数据,向渲染进程发送『提交文档』消息;
    2. 渲染进程收到『提交文档』消息后,与网络进程建立传输数据『管道』;
    3. 传输完成后,渲染进程返回『确认提交』消息给浏览器进程;
    4. 浏览器接受『确认提交』消息后,移除旧文档、更新界面、地址栏,导航历史状态等;
    5. 此时标识浏览器加载状态的小圆圈,从此前 URL 网络请求时的逆时针选择,即将变成顺时针旋转(进入渲染阶段)。

    渲染

    渲染流水线

    构建 DOM 树

    1. 输入:HTML 文档;
    2. 处理:HTML 解析器解析;
    3. 输出:DOM 树。

    样式计算

    1. 输入:CSS 文本;
    2. 处理:属性值标准化,每个节点具体样式(继承、层叠);
    3. 输出:styleSheets(CSSOM)。

    布局(DOM 树中元素的计划位置)

    1. DOM & CSSOM 合并成渲染树;
    2. 布局树(DOM 树中的可见元素);
    3. 布局计算。

    分层

    1. 特定节点生成专用图层,生成一棵图层树(层叠上下文、Clip,类似 PhotoShop 里的图层);
    2. 拥有层叠上下文属性(明确定位属性、透明属性、CSS 滤镜、z-index 等)的元素会创建单独图层;
    3. 没有图层的 DOM 节点属于父节点图层;
    4. 需要剪裁的地方也会创建图层。

    绘制指令

    1. 输入:图层树;
    2. 渲染引擎对图层树中每个图层进行绘制;
    3. 拆分成绘制指令,生成绘制列表,提交到合成线程;
    4. 输出:绘制列表。

    分块

    1. 合成线程会将较大、较长的图层(整个屏显示不完,大部分不在视口内)划分为图块(tile, 256256, 512512)。

    光栅化(栅格化)

    1. 在光栅化线程池中,将视口附近的图块优先生成位图(栅格化执行该操作);
    2. 快速栅格化:GPU 加速,生成位图(GPU 进程)。

    合成绘制

    1. 绘制图块命令——DrawQuad,提交给浏览器进程;
    2. 浏览器进程的 viz 组件,根据DrawQuad命令,绘制在屏幕上。

    结语

    此篇博客仅只是基于此问题进行详细的展开介绍,但是仍有很多细节知识点只是捎带而过,所以有想了解更多详细内容的伙伴可以自行百度搜索也可以去看看李兵老师的课程,当然也同样欢迎评论区与我一块讨论。

    展开全文
  • 1、浏览器通过DNS域名解析ip地址 2、浏览器通过TCP协议建立服务器的TCP连接(TCP三次握手)  TCP三次握手:  1)客户端发送请求连接、请求报文  2)服务端接受连接后回复ACK报文,并为此次连接分配资源 ...

    1、浏览器通过DNS域名解析到ip地址

    2、浏览器通过TCP协议建立到服务器的TCP连接(TCP三次握手)

        TCP三次握手:

            1)客户端发送请求连接、请求报文

            2)服务端接受连接后回复ACK报文,并为此次连接分配资源

            3)客户端接收到ACK报文后也向服务端发送一个ACK报文,并分配资源,由此TCP连接就建成了

                

    3、客户端(浏览器)向web服务器端发送Http协议包,请求服务器里的资源文档

    4、服务器向客户端发送Http协议应答包

    5、客户端和服务器断开连接(TCP四次挥手),客户端开始解析处理HTML文档

            TCP四次挥手:

                1)客户端发起中断连接请求,也就是发送FIN报文,告知服务端:“已经没有数据要发送给你了,但是如果你还有数据没有发送完,别急着关闭(Socket),可以继续发送”.

                2)服务端接收到FIN报文后,发送ACK报文,告知客户端,你的消息我已收到,但是我还没有准备好,请等待。此时客户端会进入等待状态(FIN_WAIT),等待服务端的FIN报文

                3)当服务端确定数据已经发送完成,向客户端发送FIN报文,告知客户端数据已发送完成,可以关闭连接

                4)客户端收到FIN报文后知道可以关闭连接,但是他不相信网络,怕服务端不知道关闭,于是会向服务端发送ACK报文并进入TIME_WAIT状态,如果服务端没有收到可以重传。服务端收到ACK后知道可以断开连接了。客户端在等待了2MSL后没有收到回复,则证明服务端已经关闭连接了,那客户端也可关闭连接了。TCP连接也就关闭

            

    展开全文
  • 输入URL到页面展示到底发生了什么

    千次阅读 多人点赞 2018-08-07 11:00:51
    刚开始写这篇文章还是挺纠结的,因为网上搜索“从输入url到页面展示到底发生了什么”,你可以搜一大堆的资料。而且面试这道题基本是必考题,二月份面试的时候,虽然知道这个过程发生了什么,不过当面试官一步步...
  • 这应该算是一个很经典的面试题了,前端工程师,后端工程师,包括网络工程师都有可能被问。开放度很高,每个人都可以针对自己熟悉的部分,进行深入的讲解。 总体来说,分为如下几个部分 1.DNS解析 2.建立TCP连接,...
  • 首先,当输入url,浏览器会先从本地硬盘的host文件,找域名对应的IP,如果有的话直接就会使用host文件中的IP, 如果没有的话,就会继续向上寻找。找到本地DNS服务器一般由网络接入服务器商提供(中国电信,中国移动...
  • 输入一个url到浏览器页面展示都经历了哪些过程

    万次阅读 多人点赞 2018-07-19 15:12:12
    在日常的浏览器访问过程中,我们肯定会访问n多页面,但是我们输入一个网址后是如何变成一个页面展示在我们目前,从一个url到页面的展示这个过程中,我们的浏览器都经历了一些什么? 步骤 → 1- 输入网址 → 2-...
  • 浏览器发起DNS查询请求(域名解析服务器是基于UDP的,53端口):浏览器作为客户端,当输入url时,浏览器中自动去请求DNS服务器,经过域名解析之后获得相应的域名对应的IP; 域名查询方式:根域名->顶级域名->次级...
  • 1、首先,在浏览器地址栏中输入url 2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳第三步操作。 3、在发送http请求前,需要域名解析(DNS解析),解析...
  • Accept:image/gif.image/jpeg.*/* Accept-Language:zh-cn Connection:Keep-Alive Host:localhost User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0) Accept-Encoding:gzip,deflate.
  • 面试题:从 URL 在浏览器被输入到页面展现的过程中发生了什么? 延伸: 现代浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开? 一个 TCP 连接可以对应几个 HTTP 请求...
  • 在浏览器输入网址时,浏览器会根据历史记录、书签智能匹配补全域名或者 url 。 例如 chrome 浏览器,甚至会根据匹配结果直接把网页加载出来。 解析域名 请求发起时,浏览器首先解析域名,一般会首先查看本地的 hosts...
  • 【译】从输入URL到页面渲染完成

    千次阅读 2017-04-25 20:46:43
    原文链接:从输入URL到页面渲染完成 作为一个软件开发者,你一定会对网络应用如何工作有一个完整的层次化的认知,同样这里也包括这些应用所用到的技术:像浏览器,HTTP,HTML,网络服务器,需求处理等等。...
  • 引言 简单的说可以分为六步:1.DNS查询 / 解析、2.TCP连接: TCP三次握手、3.发送请求、4.返回响应、5.渲染页面、6.... 从第一步第六步,每一个知识点都...在浏览器中输入url 用户输入url,比如http://www.google....
  • 我们平常在地址栏里输入一些网址时,页面很快就会出现,但在这之中到底发生了什么事情呢? 大概是这样的流程: 在浏览器的地址栏中敲入了url 域名解析 服务器处理请求 浏览器处理 绘制网页 一、在浏览器的地址栏中敲...
  • 输入URL到浏览器显示页面发生了什么

    万次阅读 多人点赞 2017-08-13 23:51:35
    当在浏览器地址栏输入网址,如:www.baidu.com后浏览器是怎么把最终的页面呈现出来的呢?这个过程可以大致分为两个部分:网络通信和页面渲染。 一、网络通信  互联网内各网络设备间的通信都遵循TCP/IP协议,利用...
  • 页面输入URL到展现发生了什么

    千次阅读 2018-04-18 13:48:48
    我们在浏览器上输入地址时,如www.qq.com,需要把这个地址解析成ip地址,其中就需要dns解析。 DNS(Domain Name System)是域名系统的英文缩写,他的服务是用来将主机名和域名转换为ip地址的工作。 dns域名 ...
  • 一般可分为如下 7 个步骤:1、浏览器中输入网址。2、发送至 DNS 服务器并获得域名对应的 WEB 服务器的 ip 地址。DNS 解析首先会从你的浏览器的缓存中去寻找是否有这个网址对应的 IP 地址,如果没有就向OS系统的 DNS ...
  • URL 输入到页面展现到底发生什么?   前言 一、URL 到底是啥 二、域名解析(DNS) 1. IP 地址 2. 什么是域名解析 3. 浏览器如何通过域名去查询 URL 对应的 IP 呢 4. 小结 三、TCP 三次...
  • 输入URL到网页呈现的过程

    千次阅读 2018-03-24 10:30:36
    当我们在浏览器中输入一个URL,例如”www.google.com”时,这个地址并不是谷歌网站真正意义上的地址。互联网上每一台计算机的唯一标识是它的IP地址,因此我们输入的网址首先需要先解析为IP地址,这一过程叫做DNS解析...
  • 面试的时候被问这个问题好几次,总的来说查阅资料显示,总体被分为这样几个过程  1、DNS解析  2、TCP连接  3、发送HTTP请求  4、服务器处理请求并且返回HTTP报文  5、浏览器解析并且渲染页面  6、连接...
  • 简单来说浏览器就是一个由地址栏、菜单栏、选项卡、页面窗口、和状态栏组成的应用程序,但这仅仅是我们从表面上看到的。那么实际来讲远远不止这些,在浏览器的背后还有更多更复杂的逻辑和组件,比如浏览器引擎,渲染...
  • 2019-2-10 面试准备,第一次练习 浏览器从接收一个url,最后的页面展示,其中经历了哪些过程?又会用到哪些协议呢? ... 一、浏览器从接收一个url,最后的页面展示... 1、在浏览器地址栏中输入URL  2、DN...
  • 输入网址浏览器渲染页面的过程

    千次阅读 2018-07-31 08:00:47
    1) 在客户端浏览器中输入网址URL。 2) 发送DNS(域名服务器)获得域名对应的WEB服务器的IP地址。 3) 客户端浏览器与WEB服务器建立TCP(传输控制协议)连接。 4) 客户端浏览器向对应IP地址的WEB服务器发送相应的...
  • 最近在进行前端面试方面的一些准备,看了网上许多相关的文章,发现有一个问题始终绕不开: 在浏览器中输入URL到整个页面显示在用户面前时这个过程中到底发生了什么。仔细思考这个问题,发现确实很深,这个过程涉及...
  •  我们使用浏览器去浏览网址但是我们却不知道这个过程中到底发生了什么,本篇博文就是讲述在浏览器输入url之后浏览器展现出页面这一过程中都是发生了什么,是如何发生的。DNS域名解析 -> 建立TCP连接 -> 发送HTTP...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,109
精华内容 39,243
关键字:

输入url到页面展示