Web性能优化宝典

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等等,非常直观。

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

 

 

 

 

 

 

 

 

 

 

 

 

后记

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

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

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. C#语言方面... 4 1.1 垃圾回收... 4 1.1.1 避免不必要的对象创建... 4 1.1.2 不要使用空析构函数 ★... 4 1.1.3 实现 IDisposable 接口... 4 1.2 String 操作... 5 1.2.1 使用 StringBuilder 做字符串连接... 5 1.2.2 避免不必要的调用 ToUpper 或 ToLower 方法... 5 1.2.3 最快的空串比较方法... 6 1.3 多线程... 6 1.3.1 线程同步... 6 1.3.2 使用 ThreadStatic 替代 NameDataSlot ★... 7 1.3.3 多线程编程技巧... 7 1.4 类型系统... 8 1.4.1 避免无意义的变量初始化动作... 8 1.4.2 ValueType 和 ReferenceType. 8 1.4.3 尽可能使用最合适的类型... 9 1.5 异常处理... 10 1.5.1 不要吃掉异常★... 10 1.5.2 不要吃掉异常信息★... 10 1.5.3 避免不必要的抛出异常... 10 1.5.4 避免不必要的重新抛出异常... 10 1.5.5 捕获指定的异常,不要使用通用的System.Exception. 10 1.5.6 要在finally里释放占用的资源... 11 1.6 反射... 11 1.6.1 反射分类... 12 1.6.2 动态创建对象... 12 1.6.3 动态方法调用... 12 1.6.4 推荐的使用原则... 12 1.7 基本代码技巧... 13 1.7.1 循环写法... 13 1.7.2 拼装字符串... 13 1.7.3 避免两次检索集合元素... 13 1.7.4 避免两次类型转换... 14 1.7.5为字符串容器声明常量,不要直接把字符封装在双引号" "里面。... 14 1.7.6 用StringBuilder代替使用字符串连接符 “+”. 14 1.7.7 避免在循环体里声明变量,... 15 1.8 Hashtable. 15 1.8.1 Hashtable机理... 15 1.8.2 使用HashTale代替其他字典集合类型的情形:... 16 1.9 避免使用ArrayList。... 16 1.10从XML对象读取数据... 17 1.11 避免使用递归调用和嵌套循环,... 17 1.12 使用适当的Caching策略来提高性能... 17 2. Ado.Net 17 2.1 应用Ado.net的一些思考原则... 18 2.2 Connection. 18 2.2.1 在方法中打开和关闭连接... 18 2.2.2 显式关闭连接... 18 2.2.3 确保连接池启用... 19 2.2.4 不要缓存连接... 19 2.3 Command. 19 2.3.1 使用ExecuteScalar和ExecuteNonQuery. 19 2.3.2 使用Prepare. 19 2.3.3 使用绑定变量 ★... 19 2.4 DataReader 20 2.4.1 显式关闭DataReader 20 2.4.2 用索引号访问代替名称索引号访问属性... 20 2.4.3 使用类型化方法访问属性... 20 2.4.4 使用多数据集... 20 2.5 DataSet 21 2.5.1 利用索引加快查找行的效率... 21 2. 使用DataView.. 21 3.ASP.NET. 21 3.1 减少往返行程(Reduce Round Trips)... 21 3.2 避免阻塞和长时间的作业... 22 3.3 使用缓存... 22 3.4 多线程... 22 3.5 系统资源... 23 3.6 页面处理... 23 3.7 ViewState. 23 4.JScript 24 4.1 JScript性能优化的基本原则... 24 4.2 JScript语言本身的优化... 24 4.3 DOM相关... 27 4.4 其他... 28

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值