现在的位置: 首页 > 综合 > 正文

Web性能优化宝典

2013年08月21日 ⁄ 综合 ⁄ 共 6582字 ⁄ 字号 评论关闭

Web性能优化宝典

绪论

性能优化一直是系统开发和项目维护中经久不衰的话题,性能问题也往往是程序员们谈虎色变的诟病。随着互联网的高速发展,越来越多的应用系统已经以web的形式摆上了台面。而在Web系统中,性能问题绝大部分体现为页面的快速响应和系统的持续稳定。根据yahoo的调查,后台只占5%,而前端高达95%之多,其中有88%的东西是可以优化的。

虚话不多说,就以业界的2-5-8原则来拉开本次Web性能优化话题的篇章吧。

当用户能够在2秒以内得到响应时,会感觉系统的响应很快,用户体验非常好

当用户在2-5之间得到响应时,会感觉系统的响应速度还可以

当用户在5-8以内得到响应时,会感觉系统的响应速度很慢,勉强可以使用

当用户在超过8后仍然无法得到响应时,会感觉系统糟透了,或者认为系统已经失去响应,而选择离开这个Web站点

 

 

 

 

 

 

 

1 兵法篇

凡用兵之道,以法为首。有法可依者,制胜之方也。

 

内容(Content)方面

1)尽量减少HTTP请求次数

    终端用户响应的时间中,大部分是在下载各项内容。这部分时间包括下载页面中的图像、样式表、脚本、Flash等。通过减少页面中的元素可以减少HTTP请求的次数。

减少HTTP请求的方式通常有:

1.合并文件。通过把所有的脚本放到一个文件中来减少HTTP请求的方法,如可以简单地把所有的CSS文件都放入一个样式表中。

2.CSS Sprites。减少图像请求的有效方法。把所有的背景图像都放到一个图片文件中,然后通过CSS的background-image和background-position属性来显示图片的不同部分;

 

2)减少DOM元素数量

关注以下原则:

1. 一个复杂的页面意味着需要下载更多数据,同时也意味着JavaScript遍历DOM的效率越慢。

2. 只有在语意上有意义时才使用<div>,而不是因为它具有换行效果才使用它。

3. 一个页面的Dom应尽量控制在500个之内,计算Dom元素个数的方法可以通过document.getElementsByTagName('*').length获得。

 

3)使iframe的数量最小

Iframe让页面无缝集成的特性使之在Web系统中大受青睐,但同时我们也要看到iframe的缺点,不能滥用iframe:

1. 即时内容为空,加载也需要时间。

2. 会阻止页面加载。

3. 没有语意的iframe请使用div代替,完全可以实现同样的效果。

4. 对客户端的负荷相对较重。

 

4)减少DNS查询   

一次DNS的解析过程会消耗20-120毫秒的时间,在dns查询结束之前,浏览器不会下载该域名下的任何东西。所以减少dns查询的时间可以加快页面的加载速度。建议一个页面所包含的域名数尽量控制在2-4个。

 

5)不要出现404错误   

HTTP请求时间消耗是很大的,因此使用HTTP请求来获得一个没有用处的响应(例如404没有找到页面)是完全没有必要的,它只会降低用户体验而不会有一点好处。

 

 

服务端(server)方面

1)采用缓存机制

缓存机制指的是促使客户端在访问系统时,尽量采用本地缓存文件,避免与服务端进行重复的交互。这种方式能够最大程度的减轻服务端和网络的负荷,有效提高页面性能。

httpResponse.addHeader("Cache-Control","private,max-age=86400");//缓存一天

需要注意的是,通常缓存仅针对静态资源而言,如图片,XML,JS,CSS等。对于动态数据是不能采取缓存的。因此在服务端做缓存时,需要根据后缀名做区分。

<filter-mapping>

  <filter-name>staticResouceCacheFilter</filter-name>

  <url-pattern>*.gif</url-pattern>

 </filter-mapping>

 <filter-mapping>

 <filter-name>staticResouceCacheFilter</filter-name>

  <url-pattern>*.png</url-pattern>

 </filter-mapping>

 <filter-mapping>

  <filter-name>staticResouceCacheFilter</filter-name>

  <url-pattern>*.js</url-pattern>

 </filter-mapping>

 <filter-mapping>

 <filter-name>staticResouceCacheFilter</filter-name>

  <url-pattern>*.css</url-pattern>

 </filter-mapping>

 <filter-mapping>

  <filter-name>staticResouceCacheFilter</filter-name>

  <url-pattern>*.html</url-pattern>

 </filter-mapping>

 

2)采用GZip压缩

Gzip是指把文件先在服务器端进行压缩,然后再传输。这样可以显著减少文件传输的大小。传输完毕后浏览器会重新对压缩过的内容进行解压缩,并执行。gzip的压缩比例非常大,一般压缩率为85%,服务器端100K的页面可以压缩到25K左右再发送到客户端。特别强调, 所有的文本内容都应该被gzip压缩: html (php), js, css, xml, txt…

方法为,在容器的配置文件中,对http端口的配置加入如下:

<Connector port="5050"address="${jboss.bind.address}"

  maxThreads="300"strategy="ms" maxHttpHeaderSize="8192"

 emptySessionPath="false" enableLookups="false"redirectPort="5000"

  acceptCount="100"connectionTimeout="15000" maxSpareThreads="75"

  minSpareThreads="10"disableUploadTimeout="true" URIEncoding="UTF-8"

  compression="on"

  compressionMinSize="2048"

  noCompressionUserAgents="gozilla,traviata"

  compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json"/>

 

 

静态资源(JavaScript ,CSS,Image方面

1)压缩 JavaScript,CSS和Image

原因不必多赘述,另外一个角度的避免因网络情况差而出现的性能瓶颈。

 

2)正确使用和放置js和css 

请关注以下原则:

1. 将CSS样式放在页面的head区域,避免页面在加载过程中出现空白或无样式。

2. 将外联JS放在页面的head区域,避免加载不到JS的情况出现。

3. 将执行的JS放到页面的最下方,避免浏览器在解释JS时,发生阻塞而导致页面加载停滞。

4. 避免使用 CSS 中的 Expressions。

 

3)将 JavaScript 和 CSS 独立成外部文件 

觉得这一点和内容部分的“尽量减少HTTP请求数量”貌似有点冲突?其实不然。

先关注一下IE作为的HttpClient的并发能力:

IE6:1个并发

IE7:2个并发

IE8:默认6个并发且可以自行设置。

可以看到,在高版本IE的支持并发,且在网络情况良好的情况下,采用多个外联文件的方式加载js和css,可以最大程度的利用客户端和网络的资源,快速访问页面。

 

4)移除重复的脚本 

这点不说也知道,不仅是从性能上考虑,代码规范上看也是这样。不得不承认,很多时候我们会因为图一时之快而加上一些或许是重复的代码。采用一个统一的css框架和js框架可以比较好的解决这个问题。如,JQuery。

2 兵练篇

学而不用,纸上谈兵,是以为殆也。

 

以下借鉴在MDSP中做性能优化或性能攻关中各个案例,为大家讲述各式各样的性能问题的定位思路和解决之道。

 

网络不畅导致网络传输超慢,前后台交互耗时长,用户体验极其低下。(江苏移动)

问题现象:MDMC所有页面访问速度极其慢。

定位思路:

1.所有页面访问速度都慢,说明不是单页面问题而是统一性问题。如:后台CPU居高不下或内存占用异常,导致MDMC无法处理页面请求;或者是网络带宽问题;或者是MDMC的过滤器问题。

2.通过top命令发现后台资源无异常。(排除后台资源问题)

3.搭建简单tomcat环境+静态页面,访问速度仍然慢。(排除MDMC系统过滤器问题)

4.通过客户端ping命令发现网络丢包严重。(初步找到原因)

5.通过httpWatch(参考兵器篇的详细介绍)监控,发现每个http请求的时间都耗在wait阶段(进一步证实网络故障):

6.关闭服务端和客户端的防火墙,访问速度仍然慢。(排除防火墙带来的网络传输问题,最终确认问题根因为:网络本身的连通性问题

解决方案:

1.由于局方坚持保持网络现状,只能从系统方面优化。

2.根据兵法篇做服务端优化,首先采用静态资源缓存,效果相当明显。页面在使用本地缓存文件之后,访问页面的速度得到极大提升。

3.进一步采用Gzip压缩,则即使是第一次访问系统,速度也较优化前提升50%。

 

        DOM元素过多导致页面浏览的响应时间极长,用户体验极其低下。(游戏基地/越南VMS)

问题现象:MDMC的呈现详情页面访问速度极长。

定位思路:

1.其他页面访问均正常,说明是单页面问题。

2.通过IE Developer(详细介绍参见兵器篇)逐个查看页面元素,发现有2000多个<input type=”checkbox”>的dom元素。

3.查看相关页面代码,搜索checkbox,发现如下js:

for (var i=0;i<checkboxes.length;i++){….}

得知该for循环将执行2000次,每次都会操作DOM元素进行页面的重绘和渲染。

4.确认问题根因为:DOM元素过多导致页面解析和渲染时间超长

解决方案:

1.分析:checkbox的数量为何如此之多?(现网终端数目多,2000多款)

2.讨论:由于是浏览页面(只读),只需要展示选中终端即可,无需展示所有终端。

3.实施:将浏览页面改为仅展示选中终端。

问题解决。

 

文件控件元素过多,且没有清空,导致表单提交数据超大,表单提交失败,阻塞内容发布及后续流程。(动漫基地)

问题现象:MDMC的新增实体文件页面上,当实体文件到达一定数目时,提交失败表单失败,阻塞内容发布流程。

定位思路:

1.查看后台日志,发现报File size exceed。

2.查看配置文件,发现文件上传上限为2M。

3.使用httpWatch(详细介绍参见兵器篇)查看页面表单提交数据(send),总大小有3M之多。(异常现像)

4.使用IE Developer(详细介绍参见兵器篇)查看页面中有10个左右的input type=file,并且value不为空。(找到问题)

5.确认问题根因为:表单中文件控件过多,表单提交时数据超大

解决方案:

1.文件提交动作和表单提交动作不需要同时执行,否则可能会数据超大。

2.将文件提交改为动态生成input type=file的方式,并在提交成功后,remove掉input,避免页面产生冗余的DOM。

问题解决。

 

列表页面迭代设计不合理导致页面响应时间极长,用户体验低下。(动漫基地)

问题现象:MDMC的内容列表页面响应时间极长。

定位思路:

1. 使用httpWatch(详细介绍参见兵器篇)查看列表页面,发现每次访问列表页面,http请求action有11次之多。(异常现像)

2. 将列表改成每页50条,再次访问列表页面,发现http请求action有51次之多.。(次数跟分页数目有关)

3. 查看列表页面代码,发现列表在每次迭代时,会发起一个http请求。(确定问题)

4.确认问题根因为:列表页面迭代涉及不合理,导致http请求次数过多

解决方案:

1.分析:为什么要在页面迭代中再次请求?(额外的列表项需求)

2.实施:即使是额外的列表项需要展示,也应该在后台一次性获取到,并封装到列表数据对象中。

问题解决。

 

3 兵器篇

工欲善其事,必先利其器。

 

前台分析工具

1)HttpWatch Professional 

HttpWatch Professional绝对是Web性能定位分析工具的首选。该工具简单易用,并能轻量集成到IE中,实时监控http请求中从始到终的各种数据和状态。其中的URL瀑布图,TimeChart,发送数据(头),响应数据(头),是我们定位Web问题(不仅仅是性能问题)的最常用手段。另外,其Cookie,Cache等数据,更是一些Web疑难杂症的线索藏身之处。可谓是“Watch在手,数据全有”。该工具也是作者使用最频繁的武器(没有之一)。强烈推荐Web开发人员必备,人手一份。详细使用方法,请见附件中的说明。

 

 

2)IE Developer ToolBar

IE Developer ToolBar其实是一款页面Dom分析工具,它能够以树状菜单的形式描述一个完整的页面Dom结构,相应的勾勒出页面控件的形状,并能够显示每个Dom的js或css属性,便于开发人员直观的分析和定位。

 

3)FireBug 

      FireBug其实是FireFox的自带插件,其功能跟HttpWatch相差无几,只是所依附的浏览器不同。(HttpWatch也有FireFox版的插件)

 

4)Page Speed

      Page speed 是基于Firebug的1个工具,主要可以对页面进行评分,总分100分,而且会显示对各项的改进意见,Page Speed也能检测到JS的解析时间。

      对于开发人员而言,这款工具的神奇之处就是在于它能通过自动评分的方式,评价页面各项指标的好坏,让开发人员能够聚焦于正确的优化方向,大大减少自行分析和定位的时间,可以称得上是Web系统性能优化的进阶利器。

5)DynaTrace's Ajax Edition

      Web系统性能分析终极工具,Web页面的各种缺陷可以通过该工具一览无余。不但可以检测资源加载瀑布图,而且还能监控页面呈现时间,页面渲染过程,网络传输性能,客户端CPU开销,JS分析和执行时间,CSS解析时间等等。同时,它也能像PageSpeed一样给出页面各项指标的评分。熟练掌握该工具,可以精确定位Web系统的各类性能问题。附件是该工具的使用指南。

后台分析工具

1)线程和堆栈分析工具(IBM Thread and Monitor)

分析jave core文件,常用于查看阻塞线程以及分析堆栈。

2)heapdump分析工具(IBM HeapAnalyzer)

      分析java heap文件。用于查看heapdump中的java对象的占用情况,判断java大对象的GC状态。

这个工具的意义非常重大,大家都知道在java自带gz的机制,并且没有sizeOf及类似的方法用于计算对象大小,因此在定位java一些大对象带来的性能问题时,往往比较吃力。该工具能够以树形菜单和对象列表的形式将dump文件中的java对象详细展示出来,包括size, total, type等等,非常直观。

以下是该工具的使用指南。

 

 

 

 

 

 

 

 

 

 

 

 

后记

性能问题永远都不会有一个最终的完美方案。其要点在于,设计,编程,配置,测试时要有性能的概念。思考自己的每一个动作会对性能造成什么样的影响。性能的改进依赖于测试,任何改进都必须有性能测试报告来证明其是行之有效的,而不是拍脑袋拍出来的。性能的改进同时依赖于团队对于性能持久的关注,而不是有了问题才想到去解决。

希望该文档对能够让大家对性能优化问题有初步的接触和了解,认识到性能问题并不可怕,只要能够找对方向,抓住要点,实施行之有效的改进,任何性能问题都是纸老虎。

 

抱歉!评论已关闭.