受欢迎的博客标签

从网络通信角度谈web性能优化(从输入url到浏览器开始渲染页面中间都发生了什么)

Published

衡量一个网站的性能有多个指标,

DNS解析时间,

T-CP链接时间,

HTTP重定向时间,

等待服务器响应时间等等,从用户角度来看,就可以归结为该网站访问速度的快慢。也就是说性能等于网站的访问速度。


Amazon曾经做过一个统计:网页加载时间每延长1秒钟,一年将减少16亿美元的营收。


鉴于性能的重要性,我们便经常看到许多记录提升访问速度的方法:

减少http请求,

雪碧图,

压缩文件等等。

 

首先需要深入理解一个浏览器与互联网的通信过程,然后分析每个过程所占用时间,怎样的方法可以减少这些时间,以此来缩小网站总的加载时间,提升网站的访问速度。

 

cloudflare Speed test result

https://dash.cloudflare.com/dfc09f04ef21f0f5d7efab13036d41aa/iaspnetcore.com/speed

Time to First Byte TTFB

First Contentful Paint

First Meaningful Paint

First Interactive

Speed Index

Total Load time

 

 

 

Time to First Byte

TTFB 是 Time to First Byte 的缩写,指的是浏览器开始收到服务器响应数据的时间(后台处理时间+重定向时间),是反映服务端响应速度的重要指标。

就像你问朋友了一个问题,你的朋友思考了一会儿才给你答案,你朋友思考的时间就相当于 TTFB。你朋友思考的时间越短,就说明你朋友越聪明或者对你的问题越熟悉。对服务器来说,TTFB 时间越短,就说明服务器响应越快。

 

First Contentful Paint

首次内容绘制(First Contentful Paint,FCP)
这是当用户看见一些“内容”元素被绘制在页面上的时间点。和白屏是不一样的,它可以是文本的首次出现,或者 SVG 的首次出现,或者 Canvas 的首次出现等等。

因此,用户可能会产生疑问,它正在运行吗? 页面是否在他(她)键入 URL 并按 enter 键后开始加载了呢

 

First Meaningful Paint

首次有意义绘制(First Meaningful Paint,FMP)
这是指页面主要内容出现在屏幕上的时间点。

主要内容是什么?

当

博客的标题和文本
搜索引擎的搜索文本
对于电子商务产品来说重要的图片
展示的时候。

但如果展示的是

下拉菜单或类似的东西
无样式内容闪烁(FOUC)
导航条或页面标题
则不计算在主要内容之内。

FMP = 最大布局变化时的绘制

 

Speed Index是显示页面的可见部分的平均时间。它以毫秒为单位表示,会受视图端口大小的影响。
  Speed Index已于2012年4月添加到WebPagetest,衡量页面内容填充的速度(越低越好)。它特别适用于比较不同页面之间的差别(在优化之前/之后,我的网站与竞争对手等),与其它指标(Load Time,Start Render等)结合使用,可以更好地了解网站的性能 。

 

网站加载 Waiting (TTFB) 时间过长的原因和解决办法

 

从输入url到浏览器开始渲染页面中间都发生了什么

互联网内各网络设备间的通信都遵循TCP/IP协议,利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。分层由高到低分别为:应用层、传输层、网络层、数据链路层。发送端从应用层往下走,接收端从数据链路层网上走。如图所示

 

  1. 在浏览器中输入url
    用户输入url,如www.zhihu.com。其中https是协议,//后面的是网络地址,网…

  2. 浏览器查询缓存
    如果存在有效的缓存,则跳至第11步的渲染阶段。

  3. 应用层DNS解析域名
    域名是为了方便人类记忆,但计算机不能很好的处理域名,因为IP地址的长度是固定的32位(IPv6是128位),而域名的长度不固定,机器处理起来比较困难,因此需要有一个辅助系统提供域名到IP地址的映射,这个辅助系统就是DNS(Domain Name System)。 在收到一个域名后,客户端会先检查本地是否有对应的IP地址,若找到则返回响应的IP地址。若没找到则请求上级DNS服务器,直至找到根域。最终得到域名对应的IP地址,存在负载均衡时同一域名返回IP可能不同,所以IP地址才是是计算机在网络中的唯一标识。

  4. 应用层发送http请求
    http协议是用于客户端与服务器端通信的一种协议,它是通过请求和响应这种方式来实现通信的。HTTP请求包括请求报头和请求主体两个部分,其中请求报头包含了至关重要的信息,比如请求的方法(GET,POST,PUT,DELETE,CONNECT…)、目标url、遵循的协议(http / https / ftp…),以及客户端是否发送cookie等。

  5. SSL/TLS安全传输协议
    它是位于传输层之上的一个安全套接层也就是https中的’s’,确保了(1)所有信息都是加密传播的,第三方无法窃听(2)具有校验机制,一旦被篡改,通信双方会立刻发现(3)配备身份证书,防止身份被发现。
    为网络通信提供安全保障。

  6. 传输层用TCP协议传输报文
    位于传输层的TCP协议为传输报文提供可靠的字节流服务。它为了方便传输,将大块的数据分割成以报文段为单位的数据包,并为他们编号,方便服务器接收时能正确的快速还原报文信息。TCP协议通过三次握手来建立连接,通过四次挥手断开连接,保证了传输的安全可靠,下面的两张图和那后地解释了三次握手和四次挥手。



  7. 网络层IP协议查询MAC地址
    IP协议的作用是把TCP分割好的各种数据包传送给接收方,这时就需要接收方的MAC 地址,也就是物理地址。IP地址和MAC地址是一一对应的关系,一个网络设备的IP地址可以更换,但是MAC地址一般是固定不变的。ARP协议可以将IP地址解析成对应的MAC地址。当通信的双方不在同一个局域网时,需要多次中转才能到达最终的目标,在中转的过程中需要通过下一个中转站的MAC地址来搜索下一个中转目标,路由提供这种中转服务。

  8. 数据到达数据链路层被处理包装

    在找到对方的MAC地址后,就将数据发送到数据链路层,数据链路层负责三件事:封装成帧,透明传输,差错检测。

  1. 物理层传输到达服务器端
    数据进入物理层到达服务器后,再经历3-7的相反操作:在链路层接收到数据包,再层层向上直到应用层。这过程中包括在运输层通过TCP协议将分段的数据包重新组成原来的HTTP请求报文。

  2. 服务器响应
    服务接收到客户端发送的HTTP请求后,查找客户端请求的资源,并返回响应报文,响应报文中包括一个重要的信息——状态码。状态码由三位数字组成,其中比较常见的是200 OK表示请求成功。301表示永久重定向,即请求的资源已经永久转移到新的位置。在返回301状态码的同时,响应报文也会附带重定向的url,客户端接收到后将http请求的url做相应的改变再重新发送。

  3. 客户端接收响应并渲染页面
    服务器的响应到达客户端后,浏览器会根据接收到的数据渲染页面。渲染阶段也有许多改善性能的方案,本文的重点不在这里,下次在另一篇文章里细说。

以上就是网络通信的整个过程,深究起来极其复杂,用到的协议也是非常多!

chrome开发者模式Network下分析各个过程对应时间

chrome浏览器下按F12打开开发者工具,找到第四栏的network,在浏览器上方地址栏输入一个自己从未访问过的url,目的是保证请求的内容没被缓存在本地(为此,博主还清理了一波浏览器缓存(;′⌒`),伤心)。
整体大概是这样:

找一个有代表性的请求,如上图红色框所示,将鼠标放在黄色箭头所指的地方,会浮现该请求timeline的详情,如下图所示

这张详情图中可谓是藏了不少有价值的信息呢( •̀ ω •́ )✧,注意看咯!

  1. Resource scheduling(红色圈圈3)
    第一部分首先是资源调度的时间。
    红色圈圈告诉我们Queued at 214.06ms,在214.06 ms 时开始排队。排了0.57ms后(圈圈4),就Started at 214.63ms(圈圈2),也就是说资源调度结束后就开始处理该指令了。
    据chrome官方解释,导致Queueing的原因有以下几种:

    • 请求已被渲染引擎推迟,因为该请求的优先级被视为低于关键资源(例如脚本/样式)的优先级。 图像经常发生这种情况。
    • 请求已被暂停,以等待将要释放的不可用 TCP 套接字。
    • 请求已被暂停,因为在 HTTP 1 上,浏览器仅允许每个源拥有六个 TCP 连接。
    • 生成磁盘缓存条目所用的时间(通常非常迅速)
  2. Connection Start(圈圈5)
    资源调度后就要开始建立链接了。
    圈圈6 Stalled代表 请求等待发送所用的时间,此时间包含第一部分中的第二步:查看浏览器缓存所用的时间,下图是刷新后一个“from disk cache”文件的详情图,可以很好地证明这一点。

    圈圈7 Proxy negotiation 代表与代理服务器协商的时间
    圈圈8 DNS Lookup 执行 DNS 查询所用的时间。 页面上的每一个新域都需要完整的往返才能执行 DNS 查询。对应于第一部分中的“应用层DNS解析域名”时间
    圈圈9 Initial Connection 初始化连接所用的时间,包括 TCP 握手/重试和协商 SSL 的时间。对应于第一部分的6和7
    圈圈10 SSL 完成SSL握手所需要的时间,对应于第一部分的5

    机智的你是不是已经发现建立链接的时间刚好对应于第一部分中的3-

  3. Request/Response
    通信链接建立后,就可以发送请求了,服务器处理后返回响应,客户端再根据响应内容下一步处理

    圈圈11 Request sent 发送请求的时间,这个是非常快的
    圈圈12 Waiting(TTFB)等待服务器初始响应所用的时间,也称为至第一字节的时间。 此时间将捕捉到服务器往返的延迟时间,以及等待服务器传送响应所用的时间。
    最后是 Content Download,接受(下载)响应数据所需要的时间。

可以发现,详情图中的时间顺序和第一张网络模型示意图刚好一一对应,只有TCP/IP连接建立完成后,才能再建立SSL/TLS,最后才可用http协议请求/响应。

到这里,想必你已经明白了一次完整的请求需要经历的步骤和耗费的时间,那么这些时间中有哪些是可以人为减少的呢?我们可以通过怎样的方式来减少这些时间来提高性能呢?
看下面

优化web性能的若干方法

  1. 减少http的请求数降低connection的时间
    由上面的详情图可以看到,如果本地没有缓存时,许多时间都花在了第二步Connection Start 建立链接上,只有少部分花在了Content Download上。那好,现在如果我们把两个文件合并成一个,就可以用一次请求代替之前的两次请求,理论上是不是就节约了一次Connection的时间了?合并的文件越多,节约的时间就越多。
    所以我们可以把图片,css,js等一些可以合并的文件尽量合并来减少http的请求数,降低总的connection的时间。
    细心的朋友可能会发现,有的请求是几乎没有connection的时间的,它们的详情图长这样:

    查看request header发现其中有一个这样的键值对:

    对,就是因为它,http的keep-alive可以在一定的时间内保证连接的可复用性,减少连接时间,但它的期限是有限的,可以看到network下的请求中还是有若干次请求是有connection的时间的,所以合并文件还是必须的。

  1. 压缩文件降低content download的时间
    上图中content download的时间不算多,只有20.47ms ,但它还是可以被减少的呀,如果我们压缩了该文件,在相同物理环境下,它会变得更少呀!能减少一点是一点嘛。
    而且在一些项目中,部分文件可达几百kb,这时content download的时间就不止20ms了,所以压缩后还是能减少不少时间的。
    所以项目上线前,像一些图片啦,css,js啦,能压缩的还是尽量压缩。

  2. 使用浏览器缓存
    把网站里面更新频率比较低的静态资源缓存在浏览器中,能够很好地提升速度。事实证明的确如此。

    毕竟对于几百K的文件硬盘还是可以秒读的嘛。
    通过设置 http 头里的 Cache-Control 和 Expires 属性来设定浏览器缓存时间,另外还有 Etags 和 opcode 的缓存,根据具体情况进行选择吧

  3.  

减少DNS查找


DNS用于映射主机名和IP地址,一般一次解析需要20~120毫秒。

浏览器会首先根据页面的主机名进行域名解析,在有ISP返回结果之前页面不会加载任何内容,所以减少DNS查找可以有效降低等待时间。

  如果使用1.1.1.1 DNS,在国内的解析速度是500-600ms,使用8.8.8.8 谷歌DNS解析的是在40-60ms,使用国内本地公用DNS可以看到是4-6ms就可正常解析。

 

为达到更高的性能,DNS解析通常被多级别地缓存,如由ISP或局域网维护的caching server,本地机器操作系统的缓存(如windows上的DNS Client Service),浏览器。

IE的缺省DNS缓存时间为30分钟,Firefox的缺省缓冲时间是1分钟。

我们能做的是尽量减少一个页面的主机名,但要在浏览器最大并行下载数跟dns查找之间做权衡。根据雅虎的研究,最好将主机名控制在2-4个内。

CDN加速


CDN 的本质也属于缓存,内容分发网络,把数据缓存在里用户近的地方,使用户尽快的获取数据。
CDN 通常是部署在网络运营商的机房,这些运营商为用户提供网络服务,因此用户请求的路由会优先到达 CDN 服务器,如果存在请求的资源的话,就直接返回,以最短路径返回响应,提高了用户访问速度,同时还能够为中心机房减轻压力。其原理如下:

CDN 一般用来缓存静态资源,如css,Script脚本,静态页面,图片等,这些内容修改频率很低但是访问请求频率很高,因此放在 CDN 上能够很好的改善访问速度。

<link rel="preconnect" href="https://cdn.jsdelivr.net">

come from:https://music.liumingye.cn/playlists/598/%E6%B0%91%E8%B0%A3%E6%A6%9C

 

减少重定向


重定向是指将一个URL重新路由到另一个URL。浏览器会自动重定向请求到Location指定的URL上,也就说把之前的过程又重复一遍才能请求到真正的资源,会极大地降低用户体验。

 

参考:(www.cnblogs.com/dojo-lzz/p/…]
( seanlook.com/2015/01/07/…]
( segmentfault.com/a/119000000…]

webpagetest.org

权威又免费的在线网站速度测试 webpagetest.org