博客原文地址:Claiyre的我的博客 https://claiyre.github.io
如需转载,请在文章开头注明原文地址css
衡量一个网站的性能有多个指标,DNS解析时间,TCP连接时间,HTTP重定向时间,等待服务器响应时间等等,从用户角度来看,就能够归结为该网站访问速度的快慢。也就是说性能等于网站的访问速度。
早些年Amazon曾经作过一个统计:网页加载时间每延长1秒钟,一年将减小16亿美圆的营收。(16亿美圆是一个什么概念呢?2015年,百度整年的总营收约100亿美圆!)。
鉴于性能的重要性,因而咱们便常常看到许多记录提高访问速度的方法的文章:减小http请求,雪碧图,压缩文件等等,看了这些文章后,博主了解了一些比较广泛的提高性能的方法,可是还不明白为啥这样能提高速度呀!
做为一名有志青年,博主认为,不只要知其然,还要知其因此然。在查阅大量书籍和博文后,终于明白了其中的玄机,特此记录下来,与你们分享。html
接下来,咱们首先来深刻理解一个浏览器与互联网的通讯过程,而后分析每一个过程所占时间的多少,以及哪些过程的时间是能够减小的,再说明经过怎样的方法能够减小这些时间,以此来缩小网站总的加载时间,提高网站的访问速度。git
互联网内各网络设备间的通讯都遵循TCP/IP协议,利用TCP/IP协议族进行网络通讯时,会经过分层顺序与对方进行通讯。分层由高到低分别为:应用层、传输层、网络层、数据链路层。发送端从应用层往下走,接收端从数据链路层网上走。如图所示:github
在浏览器中输入url
用户输入url,如https://www.zhihu.com。其中https是协议,//后面的是网络地址,网络地址指出了请求的资源在哪一个计算机上。网络地址能够是IP地址,也能够是域名,这里是域名,域名更方便记忆web
浏览器查询缓存
若是存在有效的缓存,则跳至第11步的渲染阶段。chrome
应用层DNS解析域名
域名是为了方便人类记忆,但计算机不能很好的处理域名,由于IP地址的长度是固定的32位(IPv6是128位),而域名的长度不固定,机器处理起来比较困难,所以须要有一个辅助系统提供域名到IP地址的映射,这个辅助系统就是DNS(Domain Name System)。 在收到一个域名后,客户端会先检查本地是否有对应的IP地址,若找到则返回响应的IP地址。若没找到则请求上级DNS服务器,直至找到根域。最终获得域名对应的IP地址,存在负载均衡时同一域名返回IP可能不一样,因此IP地址才是是计算机在网络中的惟一标识。segmentfault
应用层发送http请求
http协议是用于客户端与服务器端通讯的一种协议,它是经过请求和响应这种方式来实现通讯的。HTTP请求包括请求报头和请求主体两个部分,其中请求报头包含了相当重要的信息,好比请求的方法(GET,POST,PUT,DELETE,CONNECT...)、目标url、遵循的协议(http / https / ftp…),以及客户端是否发送cookie等。windows
SSL/TLS安全传输协议
它是位于传输层之上的一个安全套接层也就是https中的's',确保了(1)全部信息都是加密传播的,第三方没法窃听(2)具备校验机制,一旦被篡改,通讯双方会马上发现(3)配备身份证书,防止身份被发现。浏览器
为网络通讯提供安全保障。缓存
传输层用TCP协议传输报文
位于传输层的TCP协议为传输报文提供可靠的字节流服务。它为了方便传输,将大块的数据分割成以报文段为单位的数据包,并为他们编号,方便服务器接收时能正确的快速还原报文信息。TCP协议经过三次握手来创建链接,经过四次挥手断开链接,保证了传输的安全可靠,下面的两张图和那后地解释了三次握手和四次挥手。
(图片来源于http://www.cnblogs.com/zmlctt...)
网络层IP协议查询MAC地址
IP协议的做用是把TCP分割好的各类数据包传送给接收方,这时就须要接收方的MAC 地址,也就是物理地址。IP地址和MAC地址是一一对应的关系,一个网络设备的IP地址能够更换,可是MAC地址通常是固定不变的。ARP协议能够将IP地址解析成对应的MAC地址。当通讯的双方不在同一个局域网时,须要屡次中转才能到达最终的目标,在中转的过程当中须要经过下一个中转站的MAC地址来搜索下一个中转目标,路由提供这种中转服务。
数据到达数据链路层被处理包装
在找到对方的MAC地址后,就将数据发送到数据链路层,数据链路层负责三件事:封装成帧,透明传输,差错检测。
物理层传输到达服务器端
数据进入物理层到达服务器后,再经历3-7的相反操做:在链路层接收到数据包,再层层向上直到应用层。这过程当中包括在运输层经过TCP协议将分段的数据包从新组成原来的HTTP请求报文。
服务器响应
服务接收到客户端发送的HTTP请求后,查找客户端请求的资源,并返回响应报文,响应报文中包括一个重要的信息——状态码。状态码由三位数字组成,其中比较常见的是200 OK表示请求成功。301表示永久重定向,即请求的资源已经永久转移到新的位置。在返回301状态码的同时,响应报文也会附带重定向的url,客户端接收到后将http请求的url作相应的改变再从新发送。
客户端接收响应并渲染页面
服务器的响应到达客户端后,浏览器会根据接收到的数据渲染页面。渲染阶段也有许多改善性能的方案,本文的重点不在这里,下次在另外一篇文章里细说。
以上就是网络通讯的整个过程,深究起来极其复杂,用到的协议也是很是多,不得不禁衷地佩服先人的智慧!
chrome浏览器下按F12打开开发者工具,找到第四栏的network,在浏览器上方地址栏输入一个本身从未访问过的url,目的是保证请求的内容没被缓存在本地(为此,博主还清理了一波浏览器缓存(;′⌒`),伤心)。
总体大概是这样:
找一个有表明性的请求,如上图红色框所示,将鼠标放在黄色箭头所指的地方,会浮现该请求timeline的详情,以下图所示
这张详情图中可谓是藏了很多有价值的信息呢( •̀ ω •́ )✧,注意看咯!
Resource scheduling(红色圈圈3)
第一部分首先是资源调度的时间。
红色圈圈告诉咱们Queued at 214.06ms,在214.06 ms 时开始排队。排了0.57ms后(圈圈4),就Started at 214.63ms(圈圈2),也就是说资源调度结束后就开始处理该指令了。
据chrome官方解释,致使Queueing的缘由有如下几种:
请求已被渲染引擎推迟,由于该请求的优先级被视为低于关键资源(例如脚本/样式)的优先级。 图像常常发生这种状况。
请求已被暂停,以等待将要释放的不可用 TCP 套接字。
请求已被暂停,由于在 HTTP 1 上,浏览器仅容许每一个源拥有六个 TCP 链接。
生成磁盘缓存条目所用的时间(一般很是迅速)
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-
Request/Response
通讯连接创建后,就能够发送请求了,服务器处理后返回响应,客户端再根据响应内容下一步处理
圈圈11 Request sent 发送请求的时间,这个是很是快的
圈圈12 Waiting(TTFB)等待服务器初始响应所用的时间,也称为至第一字节的时间。 此时间将捕捉到服务器往返的延迟时间,以及等待服务器传送响应所用的时间。
最后是 Content Download,接受(下载)响应数据所须要的时间。
能够发现,详情图中的时间顺序和第一张网络模型示意图恰好一一对应,只有TCP/IP链接创建完成后,才能再创建SSL/TLS,最后才可用http协议请求/响应。
到这里,想必你已经明白了一次完整的请求须要经历的步骤和耗费的时间,那么这些时间中有哪些是能够人为减小的呢?咱们能够经过怎样的方式来减小这些时间来提升性能呢?
看下面
减小http的请求数下降connection的时间
由上面的详情图能够看到,若是本地没有缓存时,许多时间都花在了第二步Connection Start 创建连接上,只有少部分花在了Content Download上。那好,如今若是咱们把两个文件合并成一个,就能够用一次请求代替以前的两次请求,理论上是否是就节约了一次Connection的时间了?合并的文件越多,节约的时间就越多。
因此咱们能够把图片,css,js等一些能够合并的文件尽可能合并来减小http的请求数,下降总的connection的时间。
细心的朋友可能会发现,有的请求是几乎没有connection的时间的,它们的详情图长这样:
查看request header发现其中有一个这样的键值对:
对,就是由于它,http的keep-alive能够在必定的时间内保证链接的可复用性,减小链接时间,但它的期限是有限的,能够看到network下的请求中仍是有若干次请求是有connection的时间的,因此合并文件仍是必须的。
压缩文件下降content download的时间
上图中content download的时间不算多,只有20.47ms ,但它仍是能够被减小的呀,若是咱们压缩了该文件,在相同物理环境下,它会变得更少呀!能减小一点是一点嘛。
并且在一些项目中,部分文件可达几百kb,这时content download的时间就不止20ms了,因此压缩后仍是能减小很多时间的。
因此项目上线前,像一些图片啦,css,js啦,能压缩的仍是尽可能压缩。
使用浏览器缓存
把网站里面更新频率比较低的静态资源缓存在浏览器中,可以很好地提高速度。事实证实的确如此,( •̀ ω •́ )✧
毕竟对于几百K的文件硬盘仍是能够秒读的嘛。
经过设置 http 头里的 Cache-Control 和 Expires 属性来设定浏览器缓存时间,另外还有 Etags 和 opcode 的缓存,根据具体状况进行选择吧
减小DNS查找
DNS用于映射主机名和IP地址,通常一次解析须要20~120毫秒。浏览器会首先根据页面的主机名进行域名解析,在有ISP返回结果以前页面不会加载任何内容,因此减小DNS查找能够有效下降等待时间。为达到更高的性能,DNS解析一般被多级别地缓存,如由ISP或局域网维护的caching server,本地机器操做系统的缓存(如windows上的DNS Client Service),浏览器。IE的缺省DNS缓存时间为30分钟,Firefox的缺省缓冲时间是1分钟。 咱们能作的是尽可能减小一个页面的主机名,但要在浏览器最大并行下载数跟dns查找之间作权衡。根据雅虎的研究,最好将主机名控制在2-4个内。
CDN加速
CDN 的本质也属于缓存,内容分发网络,把数据缓存在里用户近的地方,使用户尽快的获取数据。
CDN 一般是部署在网络运营商的机房,这些运营商为用户提供网络服务,所以用户请求的路由会优先到达 CDN 服务器,若是存在请求的资源的话,就直接返回,以最短路径返回响应,提升了用户访问速度,同时还可以为中心机房减轻压力。其原理以下:
CDN 通常用来缓存静态资源,如css,Script脚本,静态页面,图片等,这些内容修改频率很低可是访问请求频率很高,所以放在 CDN 上可以很好的改善访问速度
减小重定向
重定向是指将一个URL从新路由到另外一个URL。浏览器会自动重定向请求到Location指定的URL上,也就说把以前的过程又重复一遍才能请求到真正的资源,会极大地下降用户体验。
好了,到此本文的主要内容已所有完结了。
本文是博主在学习过程当中的一个总结,特此记录下来备忘,也但愿对其余小伙伴有所帮助。其中若有叙述不当之处,还望您能指出,一块儿探讨~
参考:(http://www.cnblogs.com/dojo-l...
(http://seanlook.com/2015/01/0...
(https://segmentfault.com/a/11...