web前端性能
由于web前端性能测试包含的知识点很多:浏览器工作原理、浏览器缓存、相关的http头信息、http状态码、完整的一个http请求及响应过程、响应时间、web前端性能测试工具以及优化方法等等,所以决定分两篇文章来总结,这一篇主要介绍一些跟web前端性能有关的一些概念,最近也在收集阅读相关文档,一边学习一边理解消化一边总结,有什么不对的希望指出。
浏览器的主要构成:
1>.用户界面 - 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分。
2>.浏览器引擎- 用来查询及操作渲染引擎的接口。
3>.渲染引擎- 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来。
4>.网络- 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。
5>. UI后端- 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。
6>. JS解释器 - 用来解释执行JS代码。
7>.数据存储 - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术
虽然不同浏览器的工作方式不完全一样,但是基本上都包括以上各组件,浏览器的核心是浏览器引擎(Browser Engine),目前市场占有率最高的几种浏览器几乎使用了不同的浏览器引擎:IE使用的是Trident,Firefox使用的是Gecko,Safari和Chrome使用的是Webkit。
一个完整的页面请求及响应过程:
1、浏览器的url请求
2、递归寻找DNS服务器
3、连接目标IP并建立TCP连接
4、向目标服务器发送http请求
5、web服务器接收请求后处理
6、web服务器返回相应的结果【无效、重定向、正确页面等】
7、浏览器接收返回的http内容
=========================================前端解析分割线==============================================
8、开始解析html文件,当然是自上而下,先是头部,后是body
9、当解析到头部css外部链接时,同步去下载,如果遇到外部js链接也是下载【不过js链接不建议放在头部,因为耽误页面第一展现时间】
10、接着解析body部分,边解析边开始生成对应的DOM树,同时等待css文件下载
11、一旦css文件下载完毕,那么就同步去用已经生成的DOM节点+CSS去生成渲染树
12、渲染树一旦有结构模型了,接着就会同步去计算渲染树节点的布局位置
13、一旦计算出来渲染的坐标后,又同步去开始渲染
14、10-13步进行过程中如果遇到图片则跳过去渲染下面内容,等待图片下载成功后会返回来在渲染原来图片的位置
15、同14步,如果渲染过程中出现js代码调整DOM树机构的情况,也会再次重新来过,从修改DOM那步开始
16、最终所有节点和资源都会渲染完成
=========================================分析结束分割线==============================================
17、渲染完成后开始page的onload事件
18、整个页面load完成
整个过程中会有很多的分别请求,所以TCP连接会很多,并且每一个用完都会自己关了,除非是keep-live类型的可以请求多次才关闭。对web应用前端性能的研究并不是为了准确的得到一个响应时间数据,实际上,web性能一部分取决于web服务器和应用服务器(建立连接、下载资源文件),另一部分取决于浏览器的实现机制、web页面上的js文件的执行等(分割线以内的步骤过程),我们并不仅仅关注页面资源的解析和展示响应时间,而是要关注总时间;我们进行web前端性能测试的目的是计算出包含页面渲染、网络传输以及服务器端解析等综合因素在内的加载时间等指标,对该页面性能进行评估分析,找出影响性能的主要因素和瓶颈,并在此结果的基础上,给出一定的优化建议和解决方案,从而提升用户体验。
Web前端响应时间与缓存有很大关联,而缓存也取决于http请求和响应头的某些信息。下面介绍下与前端性能相关的http头信息:
先来说说为什么要缓存:
1> 减少网络带宽消耗
2> 降低服务器压力
3> 减少网络延迟,加快页面加载
Web缓存的工作原理是基于一套规则(http协议头定义或HTML页面的Meta标签中定义)来帮助他们决定什么时候使用缓存中的保存的副本提高服务。分别从新鲜度和校验值两个维度来决定是使用缓存中的副本还是直接去源服务器中获取资源。
新鲜度(过期机制):也就是缓存副本有效期。一个缓存副本必须满足以下条件,浏览器会认为它是有效的,足够新的:
1. 含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;
2. 浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;
满足以上两个情况的一种,浏览器会直接从缓存中获取副本并渲染。
校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过期,浏览器需求重新获取资源内容。
看看浏览器的一些工作原理:
在先前至少有过一次有效访问后,在以后对同一URI资源的请求中,浏览器只进行两种动作:
(1)直接在缓存中去获取内容。如果先前有效访问的响应头包含Expires, max-age的话,“打开新窗口”、“输入URI回车”、“前一页”、“后一页”这些浏览器行为不会使浏览器在Expires, max-age设置的有效期时间内去访问服务器,而是在缓存中去获取内容,但是‘"刷新‘"或"重载"例外。
(2)访问服务器,根据服务器响应来获取内容。这种情况发生在设置no-cache等头标要求不缓存,或者是设置了Expires,max-age但浏览器行为是“刷新”或“重载”时候。‘Last-Modified‘、‘ETag‘、‘must-revalidate‘等有些特殊,不直接受浏览器行为影响,它们必须访问服务器后,再由服务器判断是直接发送新的资源,还是发送一个304 Not Modfied让浏览器使用缓存中的资源。用户操作的行为也会影响缓存的使用。
需要注意的一点是浏览器的缓存是根据URI进行的,当浏览器需要从某个URI获取资源时,会首先查看缓存中是否存在针对该URI的缓存内容,判断是直接使用还是去数据库重新去资源,因此需要改变web上显示的资源时,只需要在发布时使用一个与以前不同的URI即可。
关于浏览器并发数:
浏览器默认对同一域下的资源,只保持一定的连接数,会阻塞过多的连接,即规定了每个客户端只能与每个服务器建立的连接数。rfc2616建议不超过2个,但是随着家庭带宽和网速的增加,各个浏览器并没有保持rfc建议的2个连接数,不同浏览器的默认值是不一样的,对于不同的HTTP协议,其值也是不一样的,下面的表格是早期统计的一些值:
浏览器 |
HTTP 1.1 |
HTTP 1.0 |
IE 6,7 |
2 |
4 |
IE 8 |
6 |
6 |
Firefox 2 |
2 |
8 |
Firefox 3 |
6 |
6 |
Safari 3, 4 |
4 |
4 |
Chrome 1,2 |
6 |
? |
Chrome 3 |
4 |
4 |
Opera 9.6 |
4 |
4 |
总的来看,HTTP1.0下允许的连接数普遍大于HTTP1.1协议下的,是因为HTTP1.1是保持连接的,本身对同域下资源的获取就是优化的,且对资源的消耗要大于HTTP1.0。在rfc2616中说到,限制连接数的目的在于提高响应速度和避免拥塞。当然对于浏览器的连接数也是可以修改的。使用httpwatch时页面响应时间划分中的Block这个时间段主要就是浏览器并发数限制影响的。
HTTP状态码(HTTP Status Code)是由RFC 2616规范定义,用于表示Web服务器HTTP响应状态的3位数字代码。
所有状态码的第一个数字代表了响应的5种状态之一,这5种状态分别如下。
1xx消息:这一类型的状态码,代表请求已被接受,需要继续处理。
2xx成功:这一类型的状态码,代表请求已成功被服务器接收、理解并接收。
3xx重定向:这类状态码代表需要客户端采取进一步的操作才能完成请求。
4xx请求错误:这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。
5xx服务器错误:这类状态码代表了服务器在处理请求的过程中有错误或者异常状态
如使用httpwatch录制一个http请求,会返回200http状态码,表示请求已成功,请求所希望的响应头或数据体将随此响应返回;返回302表示请求的资源现在临时从不同的URI响应请求,由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。;返回304时需要与其他头信息综合查看。
其它的头信息:
1> 1. Accept-Encoding
Accept-Encoding是浏览器发出的请求头中包含的头信息域之一,用于告诉服务器所接受的页面文件的编码方式
比如:Accept-Encoding:gzip,deflate就是告诉服务器,浏览器能够接受不压缩和使用gzip压缩两种方式的页面内容。 页面压缩和不压缩之间的下载时间相差很大,直接影响web前端相应时间。对比以下两张图(使用的是Apache HTTP Server自带的ab加压工具,测试对象是我实际测试项目)
2>
2. 2. Connection
http协议是一种非面向连接的、无状态的协议。每一个http请求与其他http请求都是完全独立的。从理论上讲,每个一个http请求都会经历一个“建立连接-请求页面或资源-获得页面或资源-断开连接”的过程。但是建立和断开连接需要一定的时间和资源开销,对于非常小的页面和资源文件来说,很可能建立连接所消耗的时间甚至大于页面或资源的处理时间。为了让响应时间尽可能缩短,http协议引入了持久连接。 用于控制持久连接的http请求头就是Connection.当Connection的值设为keep-live时,浏览器与服务器之间约定使用持久连接。Httpwatch工具下Headers下header sents中可以查看Connection的Value。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。