1, 网站性能的黄金法则
网站性能的黄金法则:只有10%——20%的最终用户响应时间花在了下载html文档上,其余的80%——90%时间花在了下载页面中的所有组件(图片,脚本,样式表,flash等)上。
2, 规则1:减少HTTP请求。
(1) CSS Sprites
将多个不同的图片合并到一个图片中,需要使用到图片中的图片来做背景的html元素,可以通过使用CSS的background-position属性来定位图片背景的显示。
如:
(2) 图片地图
允许在一个图片上关联多个URL,目标URL的选择取决于用户单击图片上的那个位置
服务器端图片地图:将所有点击提交到同一个目标URL,向其传递用户单击的x,y坐标,web应用程序将根据x,y坐标映射为适当的操作。
客户端图片地图:将用户的点击映射到一个操作,无需向后端应用发送x,y坐标,映射通过html的map标签来实现。
如:
(3) 内联图片
通过data:url模式可以在web页面中包含图片,无需任何http请求。Data:可以用在任何需要指定url的地方,如script,a等标签。
格式如下:data:[<mediatype>][;base64],<data>
Data:url模式的缺陷是可能存在数据大小的限制,同时ie不支持图片内联。如果将图片内联在页面中,在跨不同页面时不会不缓存,要想被缓存可以将图片放到外部css中。
如:
(4) 合并脚本和样式表
尽量将js脚本和css脚本合并到一个文件中,可以减少http请求的数量。
3, 规则2:使用内容发布网络
内容发布网络(CDN)是一组分布在多个不同地理位置的web服务器,用于更加有效地向用户发布内容。
如果应用web服务器离用户更近,则一个http请求的响应时间将缩短,如果组件web服务器离用户更近,则可以是多个http请求响应时间缩短。CDN除了缩短响应时间外,还可以提供其他服务,备份,扩展能力和进行缓存。
一些大型的net公司都拥有他们自己的CDN,但很多是使用一个CDN服务提供商更为有效。使用CDN服务器提供商可以减少自己的成本和维护工作,但也会有一些缺点,网站响应时间可能会受到其他网站的影响,因为很多网站可能共用CDN服务器,同时控制请求web组件的修改带来了麻烦,如修改http头信息必须通过服务器提供商来完成。解决方法,一个网站同时使用两个CDN服务提供商提供服务。
4, 规则3:添加Expires头
Expires在http头中被称作:“在这一个日期/时间之后,响应将被认为是无效的”
用Expires头信息使浏览器(或代理)使用缓存来减少http请求数量,并减小http响应的大小,使web页面加载的更快。Web服务器使用Expires头来告诉web客户端它可以使用一个组件的当前副本,直到指定的时间为止。
如:Expires:Thu,15 Apr 2012 10:00:00 GMT
这是一个有效期非常长的Expires头,它告诉浏览器该响应的有效性持续到2012年4月15日为止。
完善Expires头信息功能,HTTP1.1引入了Cache-Control头来克服Expires头的一些限制。因为Expires头使用的是一个特定的时间,它要求服务器和客户端的时钟严格同步。并且,过期日期需要经常检查,当达到过期日期的时候,需要在服务器中重新配置一个新日期。Canche-Control头使用max-age指令指定组件会被缓存多久。它以秒为单位定义了一个更新窗,组件被请求开始过去多少秒少于max-age,浏览器会使用缓存版本。这就避免了额外的http请求。
如:Cache-Control:max-age=30000
这是一个请求后30000秒内可以使用浏览器缓存中的副本。
使用Cache-Control可以消除Expires的限制,但对不支持HTTP1.1的浏览器,仍然可用Expires头。可以同时使用两个响应头Expires和Cache-Control max-age,对于支持Cache-Control的浏览器max-age的优先权大于Expires。如果觉得Expires的时钟同步仍然是个问题的话,可以使用mod_expires来设置时间,它的功能类型max-age。
缓存头可以用于那些长久不变的web组件上做缓存。如图片,脚本,样式表,flash等,但是html文档不应该使用长久缓存,因为它包含有动态的内容,需要时常更新。一般长久缓存web组件可以缓存在30天以上。
如果我们将web组件配置为可以有浏览器代理缓存,当这些组件改变时用户如何更新?如当设置Expires头时,直到过期日期为止用户浏览器一直会使用缓存的版本,浏览器不会去检查任何更新,直到过了过期日期。所以,即使服务器上跟新了组件,已经访问过网站的用户也大可能获取不了最新的组件(因为前一个版本已经在他们的浏览器缓存中了)。
最有效的解决方案是修改其web组件的链接,全新的请求将从原始的服务器上下载最新的内容。这样,为了确保用户能获取组件的最新版本,需要在html页面修改组件的文件名。如果要达到很好地修改web组件的名称,则可以想办法将组件名称使用变量,使得更新组件名只需要轻松的修改某个变量值。可以在组件的文件名中加入版本号,可以通过改变版本号来改变组件的文件名
5, 规则4:压缩组件
从HTTP1.1开始,web客户端可以通过HTTP请求中的Accept-Encoding头来标识对压缩的支持。
如:Accept-Encoding:gzip,deflate
如果web服务器看到请求中有这个头,就会使用客户端列出来的方法中的一种来压缩响应。Web服务器通过响应中的Content-Encoding头来通知web客户端,
如:Content-Encoding:gzip
Gzip是目前最流行和最有效的压缩方法。Deflate稍逊gzip。压缩通常能将响应的数据量减少70%。
通常很多网站都会压缩html文档,脚本,样式表等文本文档,但是图片和pdf等就不应该压缩,因为它们本就是已经被压缩了,试图对它们进行压缩只会更浪费时间和cpu资源,还可能会增加文件的大小。压缩需要成本,服务器端会花cpu资源来完成压缩,客户端也要花时间和资源来进行解压。所以,是否需要压缩文件需要考虑成本和收益,如要检测收益是否大于开销,需要考虑响应时间的大小,连接的宽带和客户端与服务器端的internet距离。通常对大于1kb或2kb的文件进行压缩。mod_gzip_minimum_file_size指令控制的希望压缩文件的最小值,默认值是500b。
如果要实现文档压缩,服务器需要进行响应的压缩支持配置。
6, 规则5:将样式表放在顶部
如果将样式表放在文档底部会导致在浏览器中阻止内容的逐步呈现。因为浏览器为了避免当样式表变化时会重绘页面中的元素,浏览器会阻止页面内容的逐步呈现,从而出现“白屏”问题。
如果样式表仍在加载,构建呈现树就是一种浪费,因为在所有样式表加载并解析完毕之前无需绘制任何东西,否则,在其准备好之前显示的内容会遇到“闪烁”(FOUC)问题。
将样式表放在底部,会出现白屏还是闪烁问题,这取决于浏览器如何加载页面,ie一般是白屏问题,Firefox一般是闪烁问题。解决方案是将样式表放到文档顶部head中。
7, 规则6:将脚本放在底部
对响应时间影响最大的是页面中的组件的数量和大小。当组件无缓存时,每下载一个组件都会产生一个http请求,如果浏览器能并行地执行http请求,那么会减少响应时间,但是HTTP1.1规范协议中,建议浏览器从每个主机名上并行地下载两个组件,默认情况下很多浏览器都遵循着这一规范。要提高下载组件的响应时间,可以将web页面平均的放在两个主机名下,这样可以并行下载4个组件,使下载组件的时间减少大约一半。从而提高页面的响应时间。
但并不是下载组件的并行数增加的越多,响应性能就越好。因为增加并行下载数量并不是没有开销的,其优劣取决于客户端的带宽和cpu速度,过的的下载反而会降低性能,经验表明,2个主机名的性能比较好。
并行下载组件能够提高响应性能,但是,在下载脚本时,并行下载实际上是被禁用的,即使使用了不同的主机名,浏览器也不会启动其他的下载。因为,脚本中可能使用到document.write来修改页面内容,因此浏览器会等待,以确保页面恰当的布局。另外,为了保证脚本能够按照正确的顺序执行,就必须串行下载,如果并行下载多个脚本,就无法保证响应是按照特定的顺序倒浏览器的,如果某个脚本比较小下载的比较快,那它就可能会首先执行。如果多个脚本之间存在依赖关系,不按照正确的顺序执行就会出现js错误。
串行下载脚本会阻塞组件的下载,从而阻塞了可视化组件的逐步呈现的响应时间,如果将脚本放在底部,则可以让可视化组件逐步呈现后在下载脚本,怎样可以使用户体验更好,致少用户看到的不在是白屏的等待,他能过清楚的知道浏览器正在处理请求工作。
8, 规则7:避免CSS 表达式
CSS表达式是动态设置CSS属性的一种强大(并且危险)的方式。CSS表达式的危险在于它的求值频率较高。
如:使用CSS表达式对页面最小宽度进行设置
width:expression( document.body.clientWidth<600?”600px”:”auto”);
min-width:600px;
上面通过CSS表达式expression方法接受一个JavaScript表达式,对页面宽度进行最小值的设置,这种方式受到ie5和之后的版本支持,其他浏览器会忽略expression表达式而使用min-width的值。
打开ie的时候,该表达式不只在页面呈现和改变大小时求值,当页面滚动,甚至用户鼠标在页面上移动时都会求值,由此我们可以看得出CSS表达式求值频率过高,浪费资源的使用,影响性能。
解决方法:避免使用CSS表达式,换用js事件处理。
9, 规则8:使用外部JS和CSS
使用外部js脚本和css样式表,可以通过设置缓存来提高他们的重用率,使用内联JS脚本和CSS样式表,可以减少http请求数,从而提高响应时间。
使用外部组件还是内联组件可以根据页面的的访问情况来决定。即可以将页面不同的情况划分为不同的访问类型。
主页类型页面:访问量大,响应能力要求高,每次会话一个页面,组件重用率低。一般可选择组件内联,减少http请求,提高响应性能。
模板型页面:访问量小,每次会话会打开多个同类型页面,组件重用率高。一般可以选择组件外联,设置缓存,提高组件的重用率。
特殊页面可以使用两全其美的方法:动态内联
如果主页要求访问量大,响应能力高,每次会话需要访问主页多次或短期内重复访问量大,组件重用率高。这种情况可以使用动态内联,该方法可以实现在内联或是外联组件间做出最佳的选择。
动态内联可以通过Cookie来完成,当用户第一次访问页面时,服务器会发现灭有cookie,于是生成一个内联组件的页面,然后服务器添加js来实现在加载完后下载外部组件并设置cookie值,下次访问页面时,服务器看到cookie,就会生成一个外部组件的页面。
加载后下载:可以将js代码关联到文档的onload事件,在一秒的延迟后(确保页面呈现完毕)下载所需的js和css组件,这可以通过创建DOM元素(script和link)并赋予指定的url来实现下载。为了避免页面中出现双重定义和双重执行,可以将这些组件放到一个不可见的iframe中,避免这些问题。
10, 规则9:减少DNS查找
访问一个网站的时候,DNS查找需要开销,通常浏览器通过查找一个给定主机名的ip地址要花费20-120毫秒的时间。在DNS查找完成之前,浏览器不能从主机名那里下载到任何东西。
DNS查找可以被缓存起来以提高性能。而这种缓存可能会也客户端的环境有关。在用户请求一个主机名之后,DNS信息会保留在操作系统的DNS缓存中(windows的DNS Client服务),之后对于该主机名的请求将无需进行过多的DNS查找,至少短时间内不需要。
当然浏览器也拥有其自己的缓存,和操作系统的缓存相分离,只要浏览器中保存了DNS记录,它就不会去麻烦操作系统请求这个记录,只有当浏览器缓存丢弃了记录时,他才会向操作系统询问地址,然后操作系统或者通过其缓存来响应这个请求查询,如果缓存记录失效,则需要请求远程DNS服务器查询,这时就会发生潜在的速度降低。
从DNS的查询过程中,可以得知影响DNS缓存的有两个缓存,一个是用户计算机操作系统的缓存,一个是浏览器缓存。服务器可以表明记录可以被缓存多久,查找返回的DNS记录可以包含一个存活时间(Time-to-live TTL)值。该值告诉客户端系统可以对该值缓存多久。尽管操作系统缓存会考虑TTL值,但浏览器通常会忽略该值,并设置它自己的时间限制,HTTP协议中设置Keep-Alive特性可以同时覆盖TTL和浏览器的时间限制,就只说只要浏览器和web服务器保持通信,保持TCP连接打开的状态,就没有理由进行DNS查询。当然浏览器缓存的DNS记录数也有限,当打开的网站多了,DNS记录多了后就会丢失较早的DNS记录。
减少DNS查找,可以通过设置TTL和keep-Alive来解决,但是在设置这两个值的时候需要考虑自己服务器的一些因素。
11, 规则10:精简js
精简:就是从代码中移除不必要的字符以减小其大小,进而改善加载时间的实践,去除代码中的的注解以及不必要的字符(空格,换行符,制表符)。
混淆:就是在精简代码的基础上,改写一部分代码,可将函数和变量的名称转换为较短的字符串,这时代码更近精简但也更难阅读。同时也会带来相应的风险,如维护,调试等都会有一定的难度。
精简代码使用的工具:JSMin(可减小文件的21%左右),Dojo Compressor(可减小文件的25%左右)。
精简可以减小文件的21%左右,gzip压缩可以减少70%左右,两者同时使用可以减少77%左右。
12, 规则11:避免重定向
重定向:用于将用户请求从一个URL重新路由到另一个URL,重定向哟很多种,301和302是最常用的两种。
在重定向相应完毕并且下载文档完毕之前,没有任何东西显示给用户,这会有白屏问题。重定向引起的延迟也比较严重。
有一种重定向最为浪费,它们发生在URL的结尾必须出现斜线(/)而没有出现,这个时候这个请求可能会导致一个301响应,重定向给该请求加上(/)。很多web开发人员没有意识到这个问题。
如果一个网站包含目录使用了自动索引,用户就必须忍受一个到达预期的页面的重定向。这时你可以检查一下日志是否有301状态码,这能帮助你认识到多么值得去解决结尾缺少结尾斜线。
可以使用Ajax来去除白屏重定向。
13, 规则12:移除重复的脚本
重复脚本损失的性能的方式有两种:不必要的http请求和执行js所浪费的时间。
避免重复脚本出现的解决方法:js写一个检查脚本重复的方法检测重复脚本。
14, 规则13:配置Etag
Etag(Entity Tag)实体标签:是web服务器和浏览器用于确认缓存组件的有效性的一种机制。
浏览器在重用组件之前必须检测它是否仍然有效,这时,客户端会向服务器发送一个条件get请求,这个检测必须产生一个http请求,但这比简单地下载组件的效率要高的多,如果浏览器缓存中的组件是有效的(即它能和原始服务器上的组件相匹配),所以服务器不会返回整个组件,而是返回一个“304 not modified”的状态码。
服务器检测缓存中的组件和原始服务器上的组件匹配时有两种方式:比较最新修改日期,比较实体标签。
如:比较最新修改日期
客户端 请求头:GET /image/log.gif HTTP1.1
Host:www.com
服务器 响应头:HTTP 1.1 200 OK
Last-Modified: true,12 Dec 2012 11:00:00 GMT
Content-Length:1900
浏览器第一次请求组件,下一次请求,浏览器将会使用If-Modified-Since头将最新修改日期传回到原始服务器进行比较。
客户端 请求头:GET /image/log.gif HTTP1.1
Host:www.com
If-Modified-Since: true,12 Dec 2012 11:00:00 GMT
服务器 响应头:HTTP 1.1 304 Not Modified
如:比较实体标签
客户端 请求头:GET /image/log.gif HTTP1.1
Host:www.com
服务器 响应头:HTTP 1.1 200 OK
Last-Modified: true,12 Dec 2012 11:00:00 GMT
ETag:”128d37c-dn3n432-323kd”
Content-Length:1900
实体就是组件的另一种称呼,Etag是在HTTP1.1中引入的。浏览器通过If-None-Match头将ETag传回原始服务器,如果ETag是匹配的,就会返回304状态码。
客户端 请求头:GET /image/log.gif HTTP1.1
Host:www.com
If-Modified-Since: true,12 Dec 2012 11:00:00 GMT
If-None-Match: ”128d37c-dn3n432-323kd”
服务器 响应头:HTTP 1.1 304 Not Modified
ETag带来的问题:通常使用组件的某些属性来构造实体标签,这些属性对特定的,寄宿了网站的服务器来说是唯一的。当浏览器从一台服务器上获取了原始组件后,又向另一台服务器发起了条件get请求,这时,ETag是不会匹配的,而这对于服务器集群来处理请求的网站来说,这是一种很常见的情况。这种情况下就很难做的匹配组件,造成请求性能下降。
解决方法就是建议在集群中配置移除ETag,在Apache配置文件中简单地添加下面一行配置就能移除ETag---------------FileETag none
15, 规则14:使用Ajax可缓存
Ajax请求是可优化的,可以使用规则4(压缩组件),规则9(减少DNS查找),规则10(精简js),规则11(避免重定向),规则13(ETag用还是不用)来对ajax请求进行优化。
如果我们相对ajax请求进行缓存就要做特殊处理,ajax请求的内容一般都是动态的。要对动态的内容进行可缓存,除了做规则3 的处理外,还需要进行更多的工作,需要将响应的个性化和动态本质反映到缓存中去。可采用的最好方式是使用查询字符串参数方式。
如果一个ajax请求所产生的动态内容和这个人有关,那么可以将用户id放到查询字符串中来做到这一点。即可以在请求url后面加上用户id的参数,这样,当用户id改变时,url整体也会改变,url的改变缓存也会失效,这样就可以使得缓存和某些特定的因素绑定在一起,从而可以达到动态内容的缓存。
优化方向 | 方法手段 |
减少http请求 | CSS Sprites,合并脚本和样式表,避免重定向 |
减小请求包 | 压缩图片脚本,分屏加载,前端缓存 |
减少请求时间 | 内容服务器,js后置,使用外部js和css,减少DNS查询 |
分享到:
相关推荐
高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf
高性能网站建设指南 “如果实现了Steve这些建议中的20%,你的站点就能出现戏剧性的变化。有了这本书和YSlow扩展,实在是没有理由再构建出运行速度缓慢的网站了。” ——Joe Hewitt,Firebu9调试器和Mozilla的DOM...
《高性能网站建设指南》系列是针对Web开发者的一套宝贵资源,旨在提供网站性能优化的最佳实践。这一系列包括两本书——《高性能网站建设指南》和《高性能网站建设进阶指南》,涵盖了从基础到高级的全方位优化技巧。 ...
高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf高性能网站建设指南.pdf
《高性能网站建设指南》是一本深度探讨如何构建高效、快速响应且用户体验优良的网站的专业书籍。在当前互联网环境中,网站性能已经成为提升用户满意度、降低跳出率、优化搜索引擎排名的关键因素。这本书详细介绍了...
在《高性能网站建设指南》中,作者给出了14条具体的优化原则,每一条原则都配以范例佐证,并提供了在线支持。《高性能网站建设指南》内容丰富,主要包括减少HTTP请求、Edge Computing技术、Expires Header技术、Gzip...
《高性能网站建设指南》是一本深度探讨如何构建快速、高效、用户体验优秀的网站的专业书籍。这本书针对的是网站开发者、设计师以及对网站性能优化有兴趣的读者。它不仅涵盖了基础的网页设计原则,还深入剖析了提高...
《高性能网站建设指南》是一本专注于优化网站前端性能的电子书,以PDF格式提供,旨在帮助开发者和网站管理员提升用户体验,降低服务器负担。本书的核心内容涵盖了多个关键领域,旨在通过科学的方法和技术来加速网页...
《高性能网站建设指南》结合Web2.0以来Web开发领域的最新形势和特点,介绍了网站性能问题的现状、产生的原因,以及改善或解决性能问题的原则、技术技巧和最佳实践。重点关注网页的行为特征,阐释优化Ajax、CSS、...
《高性能网站建设指南》是一本深度探讨如何提升网站性能的专业书籍,由Steve Souders撰写,中文版和英文原版都包含在压缩包中。这本书针对Web开发者和网站优化人员,提供了许多实用的策略和技巧,旨在帮助他们创建更...
《高性能网站建设指南》是一本深度探讨如何提升网站性能和速度的专业书籍。这本书涵盖了从前端到后端,从HTML到CSS的全方位优化策略,旨在帮助开发者和网站管理员构建快速响应、用户体验优秀的网站。以下是对其中...